@vellumai/assistant 0.6.6 → 0.7.1

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 (1603) hide show
  1. package/AGENTS.md +20 -0
  2. package/ARCHITECTURE.md +46 -38
  3. package/Dockerfile +27 -6
  4. package/README.md +9 -11
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +83 -149
  6. package/bun.lock +309 -119
  7. package/docs/architecture/memory.md +1 -90
  8. package/docs/architecture/security.md +28 -41
  9. package/docs/credential-execution-service.md +7 -5
  10. package/docs/skills.md +10 -10
  11. package/docs/stt-provider-onboarding.md +17 -45
  12. package/examples/plugins/echo/bun.lock +25 -0
  13. package/knip.json +9 -22
  14. package/node_modules/@vellumai/ces-client/bun.lock +33 -0
  15. package/node_modules/@vellumai/ces-client/package.json +25 -0
  16. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +631 -0
  17. package/node_modules/@vellumai/ces-client/src/__tests__/package-boundary.test.ts +138 -0
  18. package/node_modules/@vellumai/ces-client/src/credential-rpc.ts +13 -0
  19. package/node_modules/@vellumai/ces-client/src/http-credentials.ts +296 -0
  20. package/node_modules/@vellumai/ces-client/src/http-log-export.ts +111 -0
  21. package/node_modules/@vellumai/ces-client/src/index.ts +43 -0
  22. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +445 -0
  23. package/node_modules/@vellumai/credential-storage/src/__tests__/package-boundary.test.ts +32 -6
  24. package/node_modules/@vellumai/egress-proxy/src/__tests__/package-boundary.test.ts +32 -1
  25. package/node_modules/@vellumai/gateway-client/bun.lock +39 -0
  26. package/node_modules/@vellumai/gateway-client/package.json +23 -0
  27. package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +343 -0
  28. package/node_modules/@vellumai/gateway-client/src/__tests__/package-boundary.test.ts +140 -0
  29. package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +422 -0
  30. package/node_modules/@vellumai/gateway-client/src/index.ts +35 -0
  31. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +331 -0
  32. package/node_modules/@vellumai/gateway-client/src/types.ts +131 -0
  33. package/node_modules/@vellumai/gateway-client/tsconfig.json +20 -0
  34. package/node_modules/@vellumai/{ces-contracts → service-contracts}/bun.lock +1 -1
  35. package/node_modules/@vellumai/{ces-contracts → service-contracts}/package.json +4 -2
  36. package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts +5 -1
  37. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +155 -0
  38. package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +23 -0
  39. package/node_modules/@vellumai/service-contracts/src/index.ts +25 -0
  40. package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts} +6 -28
  41. package/node_modules/@vellumai/service-contracts/src/trust-rules.ts +116 -0
  42. package/node_modules/@vellumai/service-contracts/tsconfig.json +20 -0
  43. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +887 -0
  44. package/node_modules/@vellumai/skill-host-contracts/bun.lock +24 -0
  45. package/node_modules/@vellumai/skill-host-contracts/package.json +18 -0
  46. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +86 -0
  47. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +1342 -0
  48. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +6 -0
  49. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +11 -0
  50. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +32 -0
  51. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +325 -0
  52. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +444 -0
  53. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +20 -0
  54. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +12 -0
  55. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  56. package/node_modules/@vellumai/slack-text/package.json +18 -0
  57. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  58. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  59. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  60. package/openapi.yaml +3136 -650
  61. package/package.json +15 -7
  62. package/scripts/check-circular-deps.ts +80 -0
  63. package/scripts/generate-openapi.ts +29 -107
  64. package/{src/memory/graph/inspect.ts → scripts/memory-inspect.ts} +27 -27
  65. package/src/__tests__/access-request-decision.test.ts +2 -11
  66. package/src/__tests__/acp-session.test.ts +4 -150
  67. package/src/__tests__/actor-token-service.test.ts +17 -678
  68. package/src/__tests__/agent-loop-callsite-precedence.test.ts +2 -6
  69. package/src/__tests__/agent-loop-override-profile.test.ts +404 -0
  70. package/src/__tests__/agent-loop-thinking.test.ts +4 -4
  71. package/src/__tests__/agent-wake-override-profile.test.ts +283 -0
  72. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -1
  73. package/src/__tests__/anthropic-provider.test.ts +183 -28
  74. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  75. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  76. package/src/__tests__/app-routes-csp.test.ts +106 -55
  77. package/src/__tests__/approval-cascade.test.ts +3 -370
  78. package/src/__tests__/approval-conversation-turn.test.ts +3 -8
  79. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
  80. package/src/__tests__/approval-primitive.test.ts +2 -1
  81. package/src/__tests__/approval-routes-http.test.ts +36 -464
  82. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  83. package/src/__tests__/assistant-event.test.ts +0 -5
  84. package/src/__tests__/assistant-events-sse-hardening.test.ts +107 -92
  85. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  86. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -3
  87. package/src/__tests__/attachment-upload-trusted-source.test.ts +139 -0
  88. package/src/__tests__/attachments-store.test.ts +46 -1
  89. package/src/__tests__/audit-log-rotation.test.ts +2 -1
  90. package/src/__tests__/auto-analysis-end-to-end.test.ts +8 -20
  91. package/src/__tests__/background-shell-bash.test.ts +227 -0
  92. package/src/__tests__/background-shell-host-bash.test.ts +465 -0
  93. package/src/__tests__/background-tool-registry.test.ts +145 -0
  94. package/src/__tests__/background-tool-routes.test.ts +175 -0
  95. package/src/__tests__/btw-routes.test.ts +147 -183
  96. package/src/__tests__/call-controller.test.ts +15 -2
  97. package/src/__tests__/call-conversation-messages.test.ts +2 -1
  98. package/src/__tests__/call-domain.test.ts +2 -2
  99. package/src/__tests__/call-pointer-messages.test.ts +11 -13
  100. package/src/__tests__/call-recovery.test.ts +2 -1
  101. package/src/__tests__/call-routes-http.test.ts +3 -14
  102. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  103. package/src/__tests__/call-store.test.ts +2 -1
  104. package/src/__tests__/cancel-resolves-conversation-key.test.ts +31 -62
  105. package/src/__tests__/canonical-guardian-store.test.ts +2 -2
  106. package/src/__tests__/catalog-files.test.ts +0 -26
  107. package/src/__tests__/ces-rpc-credential-backend.test.ts +1 -1
  108. package/src/__tests__/channel-approval-routes.test.ts +88 -344
  109. package/src/__tests__/channel-approval.test.ts +9 -7
  110. package/src/__tests__/channel-approvals.test.ts +34 -197
  111. package/src/__tests__/channel-delivery-store.test.ts +11 -10
  112. package/src/__tests__/channel-guardian.test.ts +114 -171
  113. package/src/__tests__/channel-readiness-service.test.ts +8 -6
  114. package/src/__tests__/channel-reply-delivery.test.ts +3 -19
  115. package/src/__tests__/channel-retry-sweep.test.ts +2 -5
  116. package/src/__tests__/checker.test.ts +272 -3933
  117. package/src/__tests__/circuit-breaker-pipeline.test.ts +1 -1
  118. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +208 -0
  119. package/src/__tests__/cli.test.ts +1 -38
  120. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  121. package/src/__tests__/compaction-events.test.ts +2 -1
  122. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  123. package/src/__tests__/compaction-strip-metadata-clear.test.ts +2 -2
  124. package/src/__tests__/compaction-timeout-recovery.test.ts +1 -1
  125. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -7
  126. package/src/__tests__/config-model-image-provider.test.ts +0 -1
  127. package/src/__tests__/config-schema-cmd.test.ts +1 -1
  128. package/src/__tests__/config-schema.test.ts +36 -269
  129. package/src/__tests__/config-watcher.test.ts +12 -0
  130. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -25
  131. package/src/__tests__/connection-policy.test.ts +1 -52
  132. package/src/__tests__/contact-store-user-file.test.ts +2 -1
  133. package/src/__tests__/contacts-tools.test.ts +56 -29
  134. package/src/__tests__/contacts-write.test.ts +8 -125
  135. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  136. package/src/__tests__/context-search-agent-protocol.test.ts +230 -0
  137. package/src/__tests__/context-search-agent-runner.test.ts +998 -0
  138. package/src/__tests__/context-search-conversations-source.test.ts +320 -0
  139. package/src/__tests__/context-search-fanout.test.ts +380 -0
  140. package/src/__tests__/context-search-memory-source.test.ts +430 -0
  141. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  142. package/src/__tests__/context-search-pkb-source.test.ts +493 -0
  143. package/src/__tests__/context-search-types.test.ts +95 -0
  144. package/src/__tests__/context-search-workspace-source.test.ts +532 -0
  145. package/src/__tests__/context-window-manager.test.ts +71 -0
  146. package/src/__tests__/conversation-abort-tool-results.test.ts +10 -1
  147. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +633 -0
  148. package/src/__tests__/conversation-agent-loop-overflow.test.ts +117 -31
  149. package/src/__tests__/conversation-agent-loop.test.ts +1004 -15
  150. package/src/__tests__/conversation-analysis-routes.test.ts +68 -88
  151. package/src/__tests__/conversation-attachments.test.ts +9 -20
  152. package/src/__tests__/conversation-attention-store.test.ts +2 -1
  153. package/src/__tests__/conversation-attention-telegram.test.ts +15 -5
  154. package/src/__tests__/conversation-clear-safety.test.ts +53 -95
  155. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -330
  156. package/src/__tests__/conversation-crud-inference-profile.test.ts +54 -0
  157. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +63 -157
  158. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  159. package/src/__tests__/conversation-disk-view.test.ts +5 -4
  160. package/src/__tests__/conversation-fork-crud.test.ts +26 -55
  161. package/src/__tests__/conversation-fork-route.test.ts +5 -74
  162. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  163. package/src/__tests__/conversation-inference-profile-list.test.ts +128 -0
  164. package/src/__tests__/conversation-inference-profile-route.test.ts +205 -0
  165. package/src/__tests__/conversation-init.benchmark.test.ts +4 -81
  166. package/src/__tests__/conversation-key-store-disk-view.test.ts +2 -1
  167. package/src/__tests__/conversation-lifecycle.test.ts +4 -5
  168. package/src/__tests__/conversation-list-source.test.ts +2 -2
  169. package/src/__tests__/conversation-load-history-repair.test.ts +0 -1
  170. package/src/__tests__/conversation-pairing.test.ts +0 -1
  171. package/src/__tests__/conversation-pre-run-repair.test.ts +137 -297
  172. package/src/__tests__/conversation-process-callsite.test.ts +79 -3
  173. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -1
  174. package/src/__tests__/conversation-queue.test.ts +4 -41
  175. package/src/__tests__/conversation-routes-disk-view.test.ts +55 -188
  176. package/src/__tests__/conversation-routes-guardian-reply.test.ts +64 -71
  177. package/src/__tests__/conversation-routes-slash-commands.test.ts +144 -64
  178. package/src/__tests__/conversation-runtime-assembly.test.ts +295 -84
  179. package/src/__tests__/conversation-slash-commands.test.ts +30 -47
  180. package/src/__tests__/conversation-slash-queue.test.ts +2 -1
  181. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  182. package/src/__tests__/conversation-speed-override.test.ts +0 -4
  183. package/src/__tests__/conversation-starter-routes.test.ts +254 -55
  184. package/src/__tests__/conversation-starters-cadence.test.ts +2 -2
  185. package/src/__tests__/conversation-store.test.ts +2 -375
  186. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  187. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  188. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  189. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -47
  190. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +6 -6
  191. package/src/__tests__/conversation-unread-route.test.ts +1 -1
  192. package/src/__tests__/conversation-usage.test.ts +255 -4
  193. package/src/__tests__/conversation-wipe.test.ts +2 -103
  194. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -1
  195. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  196. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  197. package/src/__tests__/conversations-defer-cli.test.ts +150 -0
  198. package/src/__tests__/credential-execution-admin-cli.test.ts +1 -1
  199. package/src/__tests__/credential-execution-api-key-propagation.test.ts +2 -2
  200. package/src/__tests__/credential-execution-approval-bridge.test.ts +22 -289
  201. package/src/__tests__/credential-execution-client.test.ts +1 -1
  202. package/src/__tests__/credential-execution-managed-contract.test.ts +1 -1
  203. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  204. package/src/__tests__/credential-health-service.test.ts +68 -0
  205. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  206. package/src/__tests__/credential-security-invariants.test.ts +15 -5
  207. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  208. package/src/__tests__/credentials-cli.test.ts +45 -21
  209. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  210. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  211. package/src/__tests__/daemon-credential-client.test.ts +26 -108
  212. package/src/__tests__/db-acp-history.test.ts +284 -0
  213. package/src/__tests__/db-activation-state.test.ts +240 -0
  214. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  215. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +2 -1
  216. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +248 -0
  217. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +2 -1
  218. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +116 -0
  219. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  220. package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +132 -0
  221. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  222. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  223. package/src/__tests__/delete-propagation.test.ts +3 -2
  224. package/src/__tests__/deterministic-verification-control-plane.test.ts +38 -104
  225. package/src/__tests__/dm-backfill.test.ts +3 -2
  226. package/src/__tests__/document-conversations.test.ts +332 -0
  227. package/src/__tests__/edit-propagation.test.ts +5 -7
  228. package/src/__tests__/embedding-managed-proxy-selection.test.ts +3 -3
  229. package/src/__tests__/emit-event-signal.test.ts +4 -6
  230. package/src/__tests__/empty-response-pipeline.test.ts +1 -1
  231. package/src/__tests__/events-client-registration.test.ts +441 -0
  232. package/src/__tests__/file-write-tool.test.ts +2 -4
  233. package/src/__tests__/filing-service.test.ts +197 -19
  234. package/src/__tests__/first-greeting.test.ts +156 -150
  235. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  236. package/src/__tests__/followup-tools.test.ts +2 -1
  237. package/src/__tests__/gateway-client-managed-outbound.test.ts +8 -12
  238. package/src/__tests__/gateway-only-enforcement.test.ts +2 -6
  239. package/src/__tests__/gateway-only-guard.test.ts +4 -3
  240. package/src/__tests__/gemini-provider.test.ts +276 -10
  241. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  242. package/src/__tests__/graph-extraction-event-date.test.ts +30 -0
  243. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -1
  244. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -2
  245. package/src/__tests__/guardian-action-followup-store.test.ts +2 -1
  246. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +9 -9
  247. package/src/__tests__/guardian-action-late-reply.test.ts +2 -1
  248. package/src/__tests__/guardian-action-store.test.ts +2 -1
  249. package/src/__tests__/guardian-action-sweep.test.ts +9 -8
  250. package/src/__tests__/guardian-binding-drift-heal.test.ts +3 -2
  251. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +21 -118
  252. package/src/__tests__/guardian-dispatch.test.ts +14 -11
  253. package/src/__tests__/guardian-grant-minting.test.ts +16 -17
  254. package/src/__tests__/guardian-outbound-http.test.ts +71 -106
  255. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -2
  256. package/src/__tests__/guardian-routing-invariants.test.ts +41 -92
  257. package/src/__tests__/guardian-routing-state.test.ts +15 -23
  258. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -2
  259. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +274 -0
  260. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -87
  261. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  262. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  263. package/src/__tests__/heartbeat-service.test.ts +325 -25
  264. package/src/__tests__/helpers/call-route-handler.ts +72 -0
  265. package/src/__tests__/helpers/channel-test-adapter.ts +161 -0
  266. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  267. package/src/__tests__/helpers/gateway-classify-mock.ts +67 -0
  268. package/src/__tests__/helpers/mock-logger.ts +36 -0
  269. package/src/__tests__/history-repair-pipeline.test.ts +1 -1
  270. package/src/__tests__/home-state-routes.test.ts +10 -31
  271. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  272. package/src/__tests__/host-browser-e2e-cloud.test.ts +38 -498
  273. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +35 -95
  274. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  275. package/src/__tests__/host-browser-routes.test.ts +68 -153
  276. package/src/__tests__/host-browser-ws-events-e2e.test.ts +35 -31
  277. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  278. package/src/__tests__/host-file-proxy.test.ts +44 -98
  279. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  280. package/src/__tests__/host-proxy-interface.test.ts +3 -3
  281. package/src/__tests__/host-shell-tool.test.ts +35 -72
  282. package/src/__tests__/host-transfer-pending-interactions.test.ts +144 -0
  283. package/src/__tests__/host-transfer-proxy.test.ts +723 -0
  284. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  285. package/src/__tests__/http-user-message-parity.test.ts +18 -15
  286. package/src/__tests__/inbound-invite-redemption.test.ts +3 -2
  287. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  288. package/src/__tests__/injector-chain.test.ts +25 -21
  289. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  290. package/src/__tests__/inline-command-runner.test.ts +0 -66
  291. package/src/__tests__/inline-skill-load-permissions.test.ts +41 -208
  292. package/src/__tests__/install-skill-routing.test.ts +2 -14
  293. package/src/__tests__/invite-redemption-service.test.ts +2 -1
  294. package/src/__tests__/invite-routes-http.test.ts +80 -12
  295. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -1
  296. package/src/__tests__/jobs-store-upsert-debounced.test.ts +2 -1
  297. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +157 -0
  298. package/src/__tests__/list-messages-attachments.test.ts +52 -55
  299. package/src/__tests__/list-messages-page-latest.test.ts +283 -0
  300. package/src/__tests__/list-messages-tool-merge.test.ts +16 -17
  301. package/src/__tests__/llm-call-pipeline.test.ts +7 -8
  302. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  303. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  304. package/src/__tests__/llm-context-normalization.test.ts +69 -4
  305. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  306. package/src/__tests__/llm-context-route-provider.test.ts +39 -113
  307. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -1
  308. package/src/__tests__/llm-resolver.test.ts +279 -0
  309. package/src/__tests__/llm-schema.test.ts +57 -1
  310. package/src/__tests__/llm-usage-store.test.ts +271 -5
  311. package/src/__tests__/log-export-routes.test.ts +89 -0
  312. package/src/__tests__/log-export-workspace.test.ts +28 -17
  313. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  314. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  315. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  316. package/src/__tests__/mcp-abort-signal.test.ts +2 -3
  317. package/src/__tests__/mcp-client-auth.test.ts +2 -3
  318. package/src/__tests__/memory-admin-recall.test.ts +221 -0
  319. package/src/__tests__/memory-recall-log-store.test.ts +2 -1
  320. package/src/__tests__/memory-retrieval-pipeline.test.ts +6 -8
  321. package/src/__tests__/memory-upsert-concurrency.test.ts +2 -1
  322. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  323. package/src/__tests__/migration-cross-version-compatibility.test.ts +209 -302
  324. package/src/__tests__/migration-export-http.test.ts +50 -43
  325. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  326. package/src/__tests__/migration-export-to-gcs.test.ts +531 -0
  327. package/src/__tests__/migration-import-commit-http.test.ts +82 -37
  328. package/src/__tests__/migration-import-from-gcs.test.ts +574 -0
  329. package/src/__tests__/migration-import-from-url.test.ts +34 -27
  330. package/src/__tests__/migration-import-preflight-http.test.ts +108 -108
  331. package/src/__tests__/migration-jobs-status.test.ts +164 -0
  332. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  333. package/src/__tests__/migration-transport.test.ts +115 -23
  334. package/src/__tests__/migration-validate-http.test.ts +149 -159
  335. package/src/__tests__/migration-wizard.test.ts +133 -27
  336. package/src/__tests__/mock-gateway-ipc.ts +32 -62
  337. package/src/__tests__/model-intents.test.ts +15 -2
  338. package/src/__tests__/nl-approval-parser.test.ts +13 -17
  339. package/src/__tests__/non-member-access-request.test.ts +14 -6
  340. package/src/__tests__/notification-guardian-path.test.ts +15 -8
  341. package/src/__tests__/notification-schedule-notify-dedup.test.ts +2 -1
  342. package/src/__tests__/notification-telegram-adapter.test.ts +57 -55
  343. package/src/__tests__/oauth-apps-routes.test.ts +76 -122
  344. package/src/__tests__/oauth-cli.test.ts +14 -1
  345. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  346. package/src/__tests__/oauth-provider-visibility.test.ts +3 -1
  347. package/src/__tests__/oauth-providers-routes.test.ts +78 -101
  348. package/src/__tests__/oauth-store.test.ts +22 -1
  349. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -3
  350. package/src/__tests__/openai-provider.test.ts +105 -6
  351. package/src/__tests__/openai-responses-provider.test.ts +146 -4
  352. package/src/__tests__/openrouter-provider-only.test.ts +22 -4
  353. package/src/__tests__/overflow-reduce-pipeline.test.ts +4 -9
  354. package/src/__tests__/permission-types.test.ts +3 -18
  355. package/src/__tests__/persistence-pipeline.test.ts +3 -2
  356. package/src/__tests__/pipeline-runner.test.ts +1 -1
  357. package/src/__tests__/platform-bash-auto-approve.test.ts +44 -28
  358. package/src/__tests__/platform.test.ts +11 -63
  359. package/src/__tests__/playbook-execution.test.ts +2 -1
  360. package/src/__tests__/playbook-tools.test.ts +2 -1
  361. package/src/__tests__/plugin-bootstrap.test.ts +51 -5
  362. package/src/__tests__/plugin-registry.test.ts +30 -0
  363. package/src/__tests__/plugin-route-contribution.test.ts +17 -11
  364. package/src/__tests__/plugin-skill-contribution.test.ts +3 -3
  365. package/src/__tests__/plugin-tool-contribution.test.ts +10 -4
  366. package/src/__tests__/plugin-types.test.ts +1 -1
  367. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  368. package/src/__tests__/pricing.test.ts +218 -5
  369. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  370. package/src/__tests__/profiler-routes.test.ts +112 -177
  371. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  372. package/src/__tests__/provider-send-message-override-profile.test.ts +273 -0
  373. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  374. package/src/__tests__/proxy-approval-callback.test.ts +6 -554
  375. package/src/__tests__/qdrant-collection-migration.test.ts +7 -7
  376. package/src/__tests__/reaction-persistence.test.ts +12 -8
  377. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  378. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  379. package/src/__tests__/recording-handler.test.ts +64 -83
  380. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  381. package/src/__tests__/registry.test.ts +1 -0
  382. package/src/__tests__/relay-server.test.ts +37 -17
  383. package/src/__tests__/require-fresh-approval.test.ts +24 -182
  384. package/src/__tests__/resolve-trust-class.test.ts +2 -1
  385. package/src/__tests__/retry-thinking-tool-choice.test.ts +19 -7
  386. package/src/__tests__/retry-verbosity-normalization.test.ts +139 -0
  387. package/src/__tests__/runtime-attachment-metadata.test.ts +26 -6
  388. package/src/__tests__/runtime-events-sse-parity.test.ts +15 -17
  389. package/src/__tests__/runtime-events-sse.test.ts +16 -33
  390. package/src/__tests__/schedule-routes.test.ts +226 -129
  391. package/src/__tests__/schedule-store.test.ts +119 -1
  392. package/src/__tests__/schedule-tools.test.ts +2 -1
  393. package/src/__tests__/scheduler-recurrence.test.ts +2 -1
  394. package/src/__tests__/scheduler-reuse-conversation.test.ts +2 -1
  395. package/src/__tests__/scheduler-wake.test.ts +356 -0
  396. package/src/__tests__/scoped-approval-grants.test.ts +2 -1
  397. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -1
  398. package/src/__tests__/search-skills-unified.test.ts +9 -15
  399. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  400. package/src/__tests__/secret-ingress-http.test.ts +36 -23
  401. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  402. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  403. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  404. package/src/__tests__/secret-response-routing.test.ts +29 -15
  405. package/src/__tests__/secret-routes-managed-proxy.test.ts +51 -103
  406. package/src/__tests__/secret-scanner.test.ts +2 -545
  407. package/src/__tests__/send-endpoint-busy.test.ts +36 -38
  408. package/src/__tests__/sequence-store.test.ts +2 -1
  409. package/src/__tests__/server-history-render.test.ts +2 -2
  410. package/src/__tests__/service-contracts-import-guard.test.ts +185 -0
  411. package/src/__tests__/set-permission-mode.test.ts +0 -10
  412. package/src/__tests__/settings-routes.test.ts +36 -69
  413. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  414. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  415. package/src/__tests__/skill-boundary-guard.test.ts +105 -0
  416. package/src/__tests__/skill-load-inline-command.test.ts +2 -2
  417. package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
  418. package/src/__tests__/skill-runtime-path.test.ts +64 -0
  419. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  420. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  421. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -32
  422. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  423. package/src/__tests__/slack-inbound-verification.test.ts +12 -64
  424. package/src/__tests__/slack-messaging-token-resolution.test.ts +1 -3
  425. package/src/__tests__/slack-reaction-approvals.test.ts +4 -4
  426. package/src/__tests__/slack-share-routes.test.ts +37 -72
  427. package/src/__tests__/subagent-call-site-routing.test.ts +79 -0
  428. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  429. package/src/__tests__/subagent-fork-spawn.test.ts +20 -28
  430. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  431. package/src/__tests__/subagent-notify-parent.test.ts +83 -109
  432. package/src/__tests__/subagent-role-registry.test.ts +3 -3
  433. package/src/__tests__/subagent-spawn-tool-fork.test.ts +52 -104
  434. package/src/__tests__/subagent-tools.test.ts +0 -1
  435. package/src/__tests__/suggestion-routes.test.ts +55 -62
  436. package/src/__tests__/system-prompt.test.ts +115 -13
  437. package/src/__tests__/task-compiler.test.ts +2 -1
  438. package/src/__tests__/task-management-tools.test.ts +2 -1
  439. package/src/__tests__/task-memory-cleanup.test.ts +2 -1
  440. package/src/__tests__/task-scheduler.test.ts +2 -1
  441. package/src/__tests__/telegram-config.test.ts +0 -1
  442. package/src/__tests__/terminal-tools.test.ts +3 -401
  443. package/src/__tests__/test-preload.ts +0 -11
  444. package/src/__tests__/thread-backfill.test.ts +947 -32
  445. package/src/__tests__/token-estimate-pipeline.test.ts +68 -15
  446. package/src/__tests__/tool-approval-handler.test.ts +21 -63
  447. package/src/__tests__/tool-audit-listener.test.ts +3 -3
  448. package/src/__tests__/tool-domain-event-publisher.test.ts +3 -39
  449. package/src/__tests__/tool-error-pipeline.test.ts +6 -6
  450. package/src/__tests__/tool-execute-pipeline.test.ts +6 -14
  451. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  452. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +69 -16
  453. package/src/__tests__/tool-executor-lifecycle-events.test.ts +31 -62
  454. package/src/__tests__/tool-executor.test.ts +336 -1654
  455. package/src/__tests__/tool-grant-request-escalation.test.ts +90 -311
  456. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  457. package/src/__tests__/tool-result-truncate-pipeline.test.ts +1 -1
  458. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  459. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  460. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  461. package/src/__tests__/trust-context-guards.test.ts +1 -1
  462. package/src/__tests__/trusted-contact-approval-notifier.test.ts +7 -15
  463. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +178 -354
  464. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +5 -151
  465. package/src/__tests__/trusted-contact-multichannel.test.ts +5 -6
  466. package/src/__tests__/trusted-contact-verification.test.ts +3 -2
  467. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  468. package/src/__tests__/turn-boundary-resolution.test.ts +2 -1
  469. package/src/__tests__/twilio-routes.test.ts +25 -66
  470. package/src/__tests__/usage-attribution.test.ts +247 -0
  471. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -7
  472. package/src/__tests__/usage-cli.test.ts +143 -0
  473. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  474. package/src/__tests__/usage-routes.test.ts +223 -90
  475. package/src/__tests__/user-plugin-loader.test.ts +54 -12
  476. package/src/__tests__/validation-results-screen.test.ts +39 -16
  477. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  478. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +51 -139
  479. package/src/__tests__/verification-control-plane-policy.test.ts +97 -19
  480. package/src/__tests__/voice-ingress-preflight.test.ts +5 -5
  481. package/src/__tests__/voice-invite-redemption.test.ts +2 -1
  482. package/src/__tests__/voice-scoped-grant-consumer.test.ts +3 -3
  483. package/src/__tests__/voice-session-bridge.test.ts +285 -106
  484. package/src/__tests__/volume-security-guard.test.ts +0 -2
  485. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -1
  486. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +3 -1
  487. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +2 -1
  488. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +1 -1
  489. package/src/__tests__/workspace-migration-052-seed-default-inference-profiles.test.ts +260 -0
  490. package/src/__tests__/workspace-migration-053-release-notes-acp-codex.test.ts +225 -0
  491. package/src/__tests__/workspace-migration-054-seed-recall-callsite.test.ts +235 -0
  492. package/src/__tests__/workspace-migration-055-release-notes-agentic-recall.test.ts +128 -0
  493. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +232 -0
  494. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  495. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  496. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  497. package/src/__tests__/workspace-migration-acp-sessions-ui.test.ts +144 -0
  498. package/src/__tests__/workspace-migration-drop-user-md.test.ts +1 -1
  499. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +252 -0
  500. package/src/acp/__tests__/client-handler.test.ts +64 -0
  501. package/src/acp/__tests__/helpers/acp-config-stub.ts +62 -0
  502. package/src/acp/__tests__/helpers/which-stub.ts +45 -0
  503. package/src/acp/__tests__/session-manager-persistence.test.ts +366 -0
  504. package/src/acp/__tests__/session-manager-startup.test.ts +159 -0
  505. package/src/acp/__tests__/session-manager.test.ts +83 -0
  506. package/src/acp/client-handler.ts +23 -139
  507. package/src/acp/index.ts +0 -15
  508. package/src/acp/resolve-agent.test.ts +291 -0
  509. package/src/acp/resolve-agent.ts +176 -0
  510. package/src/acp/session-manager.ts +193 -31
  511. package/src/acp/types.ts +2 -50
  512. package/src/agent/loop.ts +53 -15
  513. package/src/agent/message-types.ts +0 -2
  514. package/src/approvals/AGENTS.md +5 -1
  515. package/src/approvals/__tests__/guardian-feed-event.test.ts +11 -12
  516. package/src/approvals/approval-primitive.ts +3 -20
  517. package/src/approvals/guardian-decision-primitive.ts +37 -68
  518. package/src/approvals/guardian-request-resolvers.ts +38 -104
  519. package/src/avatar/character-components.ts +6 -6
  520. package/src/{config/bundled-skills/settings/tools → avatar}/identity-avatar.ts +1 -1
  521. package/src/backup/__tests__/backup-worker.test.ts +36 -10
  522. package/src/backup/__tests__/paths.test.ts +5 -4
  523. package/src/backup/__tests__/restore.test.ts +45 -28
  524. package/src/backup/backup-worker.ts +37 -12
  525. package/src/backup/paths.ts +11 -24
  526. package/src/backup/restore.ts +7 -11
  527. package/src/browser/__tests__/operations.test.ts +0 -35
  528. package/src/browser/operations.ts +1 -47
  529. package/src/browser-session/events.ts +0 -9
  530. package/src/bundler/package-resolver.ts +2 -6
  531. package/src/calls/active-call-lease.ts +1 -1
  532. package/src/calls/call-constants.ts +1 -1
  533. package/src/calls/call-controller.ts +1 -5
  534. package/src/calls/call-domain.ts +14 -14
  535. package/src/calls/call-pointer-messages.ts +4 -9
  536. package/src/calls/call-store.ts +2 -34
  537. package/src/calls/guardian-action-sweep.ts +9 -25
  538. package/src/calls/guardian-dispatch.ts +1 -20
  539. package/src/calls/guardian-question-copy.ts +0 -108
  540. package/src/calls/media-stream-audio-transcode.ts +2 -41
  541. package/src/calls/media-stream-server.ts +2 -3
  542. package/src/calls/media-stream-stt-session.ts +1 -3
  543. package/src/calls/relay-access-wait.ts +5 -8
  544. package/src/calls/relay-server.ts +15 -42
  545. package/src/calls/relay-setup-router.ts +2 -2
  546. package/src/calls/relay-verification.ts +4 -4
  547. package/src/calls/twilio-rest.ts +1 -39
  548. package/src/calls/twilio-routes.ts +160 -78
  549. package/src/calls/voice-control-protocol.ts +10 -10
  550. package/src/calls/voice-ingress-preflight.ts +2 -2
  551. package/src/calls/voice-session-bridge.ts +141 -77
  552. package/src/channels/__tests__/types.test.ts +25 -3
  553. package/src/channels/permission-profiles.ts +2 -72
  554. package/src/channels/types.ts +25 -44
  555. package/src/cli/AGENTS.md +1 -0
  556. package/src/cli/__tests__/notifications.test.ts +12 -10
  557. package/src/cli/commands/__tests__/attachment.test.ts +14 -8
  558. package/src/cli/commands/__tests__/backup.test.ts +3 -14
  559. package/src/cli/commands/__tests__/browser.test.ts +36 -31
  560. package/src/cli/commands/__tests__/cache.test.ts +175 -23
  561. package/src/cli/commands/__tests__/memory-v2.test.ts +382 -0
  562. package/src/cli/commands/__tests__/task.test.ts +36 -35
  563. package/src/cli/commands/__tests__/trust.test.ts +236 -0
  564. package/src/cli/commands/__tests__/ui-confirm.test.ts +14 -14
  565. package/src/cli/commands/__tests__/ui.test.ts +17 -17
  566. package/src/cli/commands/__tests__/watchers.test.ts +29 -29
  567. package/src/cli/commands/__tests__/webhooks.test.ts +544 -0
  568. package/src/cli/commands/attachment.ts +12 -8
  569. package/src/cli/commands/auth.ts +1 -1
  570. package/src/cli/commands/avatar.ts +192 -9
  571. package/src/cli/commands/backup.ts +18 -48
  572. package/src/cli/commands/browser.ts +52 -4
  573. package/src/cli/commands/cache-fs.ts +8 -0
  574. package/src/cli/commands/cache.ts +157 -84
  575. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  576. package/src/cli/commands/clients.ts +74 -17
  577. package/src/cli/commands/completions.ts +3 -3
  578. package/src/cli/commands/contacts.ts +241 -86
  579. package/src/cli/commands/conversations-defer.ts +364 -0
  580. package/src/cli/commands/conversations-import.ts +2 -3
  581. package/src/cli/commands/conversations.ts +63 -53
  582. package/src/cli/commands/credential-execution.ts +1 -1
  583. package/src/cli/commands/credentials.ts +139 -5
  584. package/src/cli/commands/default-action.ts +1 -1
  585. package/src/cli/commands/domain.ts +2 -2
  586. package/src/cli/commands/email.ts +7 -7
  587. package/src/cli/commands/image-generation.ts +1 -1
  588. package/src/cli/commands/keys.ts +5 -2
  589. package/src/cli/commands/mcp.ts +1 -1
  590. package/src/cli/commands/memory-v2.ts +315 -0
  591. package/src/cli/commands/memory.ts +8 -8
  592. package/src/cli/commands/notifications.ts +21 -20
  593. package/src/cli/commands/oauth/__tests__/connect.test.ts +23 -5
  594. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +1 -1
  595. package/src/cli/commands/oauth/__tests__/mode.test.ts +1 -1
  596. package/src/cli/commands/oauth/__tests__/status.test.ts +1 -1
  597. package/src/cli/commands/oauth/__tests__/token.test.ts +1 -1
  598. package/src/cli/commands/oauth/connect.ts +2 -2
  599. package/src/cli/commands/pending.ts +102 -0
  600. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -6
  601. package/src/cli/commands/platform/__tests__/connect.test.ts +23 -11
  602. package/src/cli/commands/platform/__tests__/disconnect.test.ts +22 -10
  603. package/src/cli/commands/platform/__tests__/status.test.ts +22 -10
  604. package/src/cli/commands/platform/connect.ts +3 -3
  605. package/src/cli/commands/platform/disconnect.ts +4 -6
  606. package/src/cli/commands/platform/index.ts +12 -10
  607. package/src/cli/commands/routes.ts +7 -1
  608. package/src/cli/commands/sequence.ts +7 -7
  609. package/src/cli/commands/skills.ts +264 -116
  610. package/src/cli/commands/task.ts +12 -10
  611. package/src/cli/commands/trust.ts +105 -167
  612. package/src/cli/commands/ui.ts +3 -3
  613. package/src/cli/commands/usage.ts +29 -15
  614. package/src/cli/commands/watchers.ts +8 -8
  615. package/src/cli/commands/webhooks.ts +270 -0
  616. package/src/cli/lib/daemon-avatar-client.ts +37 -0
  617. package/src/cli/lib/daemon-credential-client.ts +41 -189
  618. package/src/cli/lib/ipc-params.ts +22 -0
  619. package/src/cli/program.ts +6 -0
  620. package/src/cli.ts +1 -82
  621. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  622. package/src/config/acp-defaults.test.ts +57 -0
  623. package/src/config/acp-defaults.ts +40 -0
  624. package/src/config/acp-schema.ts +1 -1
  625. package/src/config/assistant-feature-flags.ts +18 -142
  626. package/src/config/bundled-skills/acp/SKILL.md +44 -16
  627. package/src/config/bundled-skills/acp/TOOLS.json +45 -1
  628. package/src/config/bundled-skills/acp/tools/acp-list-agents.ts +12 -0
  629. package/src/config/bundled-skills/acp/tools/acp-steer.ts +12 -0
  630. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +14 -14
  631. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -4
  632. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +11 -6
  633. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +6 -6
  634. package/src/config/bundled-skills/media-processing/services/reduce.ts +0 -13
  635. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  636. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +1 -1
  637. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
  638. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -1
  639. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +1 -1
  640. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -1
  641. package/src/config/bundled-skills/settings/SKILL.md +2 -17
  642. package/src/config/bundled-skills/settings/TOOLS.json +0 -56
  643. package/src/config/bundled-skills/subagent/SKILL.md +2 -0
  644. package/src/config/bundled-tool-registry.ts +4 -6
  645. package/src/config/env-registry.ts +12 -2
  646. package/src/config/env.ts +10 -22
  647. package/src/config/feature-flag-registry.json +38 -46
  648. package/src/config/llm-callsite-catalog.ts +12 -0
  649. package/src/config/llm-context-resolution.ts +80 -0
  650. package/src/config/llm-resolver.ts +90 -36
  651. package/src/config/loader.ts +9 -12
  652. package/src/config/schema.ts +5 -228
  653. package/src/config/schemas/__tests__/filing.test.ts +58 -0
  654. package/src/config/schemas/__tests__/memory-v2.test.ts +187 -0
  655. package/src/config/schemas/call-site-catalog.ts +271 -0
  656. package/src/config/schemas/calls.ts +5 -5
  657. package/src/config/schemas/filing.ts +12 -0
  658. package/src/config/schemas/host-browser.ts +2 -2
  659. package/src/config/schemas/inference.ts +1 -3
  660. package/src/config/schemas/ingress.ts +2 -2
  661. package/src/config/schemas/llm.ts +82 -12
  662. package/src/config/schemas/memory-retrieval.ts +2 -2
  663. package/src/config/schemas/memory-storage.ts +1 -1
  664. package/src/config/schemas/memory-v2.ts +185 -0
  665. package/src/config/schemas/memory.ts +2 -0
  666. package/src/config/schemas/security.ts +1 -102
  667. package/src/config/schemas/services.ts +52 -13
  668. package/src/config/schemas/skills.ts +5 -5
  669. package/src/config/schemas/tts.ts +1 -1
  670. package/src/config/seed-inference-profiles.ts +117 -0
  671. package/src/config/skills.ts +1 -91
  672. package/src/config/types.ts +3 -47
  673. package/src/contacts/contact-store.ts +2 -19
  674. package/src/contacts/contacts-write.ts +1 -143
  675. package/src/contacts/types.ts +8 -10
  676. package/src/context/token-estimator.ts +1 -1
  677. package/src/context/tool-result-truncation.ts +1 -1
  678. package/src/context/window-manager.ts +45 -6
  679. package/src/credential-execution/approval-bridge.ts +7 -69
  680. package/src/credential-execution/client.ts +17 -422
  681. package/src/credential-execution/feature-gates.ts +1 -2
  682. package/src/credential-execution/managed-catalog.ts +1 -1
  683. package/src/credential-execution/process-manager.ts +34 -10
  684. package/src/credential-health/credential-health-service.ts +22 -17
  685. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -13
  686. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +76 -83
  687. package/src/daemon/__tests__/daemon-skill-host.test.ts +265 -0
  688. package/src/daemon/__tests__/meet-host-supervisor.test.ts +587 -0
  689. package/src/daemon/__tests__/meet-manifest-loader.test.ts +463 -0
  690. package/src/daemon/approval-generators.ts +2 -14
  691. package/src/daemon/classifier.ts +0 -106
  692. package/src/daemon/config-watcher.ts +14 -54
  693. package/src/daemon/connection-policy.ts +1 -40
  694. package/src/daemon/conversation-agent-loop-handlers.ts +89 -9
  695. package/src/daemon/conversation-agent-loop.ts +440 -88
  696. package/src/daemon/conversation-attachments.ts +5 -81
  697. package/src/daemon/conversation-error.ts +9 -5
  698. package/src/daemon/conversation-history.ts +9 -9
  699. package/src/daemon/conversation-launch.ts +21 -136
  700. package/src/daemon/conversation-lifecycle.ts +1 -1
  701. package/src/daemon/conversation-messaging.ts +2 -1
  702. package/src/daemon/conversation-notifiers.ts +1 -1
  703. package/src/daemon/conversation-process.ts +90 -174
  704. package/src/daemon/conversation-runtime-assembly.ts +245 -164
  705. package/src/daemon/conversation-slash.ts +50 -164
  706. package/src/daemon/conversation-store.ts +344 -0
  707. package/src/daemon/conversation-surfaces.ts +27 -32
  708. package/src/daemon/conversation-tool-setup.ts +23 -202
  709. package/src/daemon/conversation-usage.ts +36 -0
  710. package/src/daemon/conversation.ts +129 -381
  711. package/src/daemon/daemon-control.ts +4 -72
  712. package/src/daemon/daemon-skill-host.ts +259 -0
  713. package/src/daemon/dictation-profile-store.ts +2 -26
  714. package/src/daemon/external-plugins-bootstrap.ts +67 -13
  715. package/src/daemon/first-greeting.ts +44 -156
  716. package/src/daemon/handlers/config-channels.ts +14 -14
  717. package/src/daemon/handlers/config-embeddings.ts +1 -1
  718. package/src/daemon/handlers/config-ingress.ts +27 -166
  719. package/src/daemon/handlers/config-model.test.ts +17 -0
  720. package/src/daemon/handlers/config-model.ts +8 -53
  721. package/src/daemon/handlers/config-telegram.ts +6 -53
  722. package/src/daemon/handlers/config-voice.ts +0 -42
  723. package/src/daemon/handlers/conversations.ts +32 -345
  724. package/src/daemon/handlers/recording.ts +27 -159
  725. package/src/daemon/handlers/shared.ts +50 -99
  726. package/src/daemon/handlers/skills.ts +55 -114
  727. package/src/daemon/host-bash-proxy.ts +67 -45
  728. package/src/daemon/host-browser-proxy.ts +65 -27
  729. package/src/daemon/host-cu-proxy.ts +40 -39
  730. package/src/daemon/host-file-proxy.ts +58 -37
  731. package/src/daemon/host-transfer-proxy.ts +538 -0
  732. package/src/daemon/lifecycle.ts +71 -272
  733. package/src/daemon/meet-host-startup.ts +51 -0
  734. package/src/daemon/meet-host-supervisor.ts +781 -0
  735. package/src/daemon/meet-manifest-loader.ts +410 -0
  736. package/src/daemon/memory-v2-startup.ts +35 -0
  737. package/src/daemon/message-protocol.ts +4 -7
  738. package/src/daemon/message-types/acp.ts +1 -0
  739. package/src/daemon/message-types/conversations.ts +23 -2
  740. package/src/daemon/message-types/host-bash.ts +1 -0
  741. package/src/daemon/message-types/host-cu.ts +1 -0
  742. package/src/daemon/message-types/host-file.ts +1 -0
  743. package/src/daemon/message-types/host-transfer.ts +42 -0
  744. package/src/daemon/message-types/integrations.ts +6 -0
  745. package/src/daemon/message-types/messages.ts +24 -23
  746. package/src/daemon/message-types/schedules.ts +1 -0
  747. package/src/daemon/message-types/settings.ts +0 -6
  748. package/src/daemon/message-types/shared.ts +5 -2
  749. package/src/daemon/message-types/subagents.ts +2 -1
  750. package/src/daemon/message-types/workspace.ts +1 -3
  751. package/src/daemon/pkb-reminder-builder.test.ts +13 -12
  752. package/src/daemon/pkb-reminder-builder.ts +8 -16
  753. package/src/daemon/process-message.ts +479 -0
  754. package/src/daemon/providers-setup.ts +14 -6
  755. package/src/daemon/server.ts +58 -1702
  756. package/src/daemon/shutdown-handlers.ts +3 -3
  757. package/src/daemon/startup-error.ts +1 -1
  758. package/src/daemon/tool-side-effects.ts +125 -107
  759. package/src/daemon/trust-context.ts +45 -0
  760. package/src/daemon/wake-target-adapter.ts +218 -0
  761. package/src/email/feature-gate.ts +1 -1
  762. package/src/events/domain-events.ts +1 -16
  763. package/src/events/tool-audit-listener.ts +5 -9
  764. package/src/events/tool-domain-event-publisher.ts +0 -10
  765. package/src/events/tool-metrics-listener.ts +1 -21
  766. package/src/events/tool-trace-listener.ts +0 -14
  767. package/src/filing/filing-service.ts +207 -55
  768. package/src/followups/followup-store.ts +3 -71
  769. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +93 -21
  770. package/src/heartbeat/heartbeat-service.ts +55 -16
  771. package/src/home/__tests__/feed-writer.test.ts +0 -4
  772. package/src/home/__tests__/phase5-exit-criteria.test.ts +18 -1
  773. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  774. package/src/home/__tests__/rollup-producer.test.ts +67 -2
  775. package/src/home/assistant-feed-authoring.ts +8 -1
  776. package/src/home/feed-types.ts +1 -1
  777. package/src/home/feed-writer.ts +1 -2
  778. package/src/home/relationship-state-writer.ts +17 -4
  779. package/src/home/rewrite-feed-title.ts +58 -0
  780. package/src/home/rollup-producer.ts +16 -3
  781. package/src/inbound/platform-callback-registration.ts +1 -17
  782. package/src/ipc/__tests__/attachment-ipc.test.ts +128 -66
  783. package/src/ipc/__tests__/browser-ipc.test.ts +72 -58
  784. package/src/ipc/__tests__/cache-ipc.test.ts +52 -107
  785. package/src/ipc/__tests__/cli-ipc.test.ts +9 -6
  786. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +253 -0
  787. package/src/ipc/__tests__/skill-server.test.ts +182 -0
  788. package/src/ipc/__tests__/socket-path.test.ts +69 -23
  789. package/src/ipc/__tests__/ui-request-route.test.ts +241 -216
  790. package/src/ipc/__tests__/watcher-ipc.test.ts +33 -33
  791. package/src/ipc/assistant-server.ts +443 -0
  792. package/src/ipc/cli-client.ts +3 -3
  793. package/src/ipc/gateway-client.test.ts +131 -0
  794. package/src/ipc/gateway-client.ts +98 -123
  795. package/src/ipc/ipc-framing.ts +281 -0
  796. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +171 -0
  797. package/src/ipc/routes/db-proxy.ts +73 -0
  798. package/src/ipc/routes/route-adapter.ts +32 -0
  799. package/src/ipc/routes/trust-rules.test.ts +123 -0
  800. package/src/ipc/skill-ipc-types.ts +54 -0
  801. package/src/ipc/skill-routes/__tests__/config.test.ts +146 -0
  802. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +388 -0
  803. package/src/ipc/skill-routes/__tests__/identity.test.ts +62 -0
  804. package/src/ipc/skill-routes/__tests__/log.test.ts +133 -0
  805. package/src/ipc/skill-routes/__tests__/memory.test.ts +178 -0
  806. package/src/ipc/skill-routes/__tests__/platform.test.ts +111 -0
  807. package/src/ipc/skill-routes/__tests__/providers.test.ts +265 -0
  808. package/src/ipc/skill-routes/__tests__/registries.test.ts +361 -0
  809. package/src/ipc/skill-routes/config.ts +47 -0
  810. package/src/ipc/skill-routes/events.ts +120 -0
  811. package/src/ipc/skill-routes/identity.ts +21 -0
  812. package/src/ipc/skill-routes/index.ts +37 -0
  813. package/src/ipc/skill-routes/log.ts +40 -0
  814. package/src/ipc/skill-routes/memory.ts +76 -0
  815. package/src/ipc/skill-routes/platform.ts +39 -0
  816. package/src/ipc/skill-routes/providers.ts +163 -0
  817. package/src/ipc/skill-routes/registries.ts +393 -0
  818. package/src/ipc/skill-server.ts +738 -0
  819. package/src/ipc/skill-socket-path.ts +20 -0
  820. package/src/ipc/socket-cleanup.ts +92 -0
  821. package/src/ipc/socket-path.ts +63 -32
  822. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +374 -0
  823. package/src/live-voice/__tests__/live-voice-archive.test.ts +525 -0
  824. package/src/live-voice/__tests__/live-voice-events.test.ts +473 -0
  825. package/src/live-voice/__tests__/live-voice-integration.test.ts +359 -0
  826. package/src/live-voice/__tests__/live-voice-metrics.test.ts +179 -0
  827. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +349 -0
  828. package/src/live-voice/__tests__/live-voice-stt.test.ts +244 -0
  829. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +337 -0
  830. package/src/live-voice/__tests__/live-voice-tts.test.ts +337 -0
  831. package/src/live-voice/__tests__/protocol.test.ts +295 -0
  832. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +413 -0
  833. package/src/live-voice/live-voice-archive.ts +758 -0
  834. package/src/live-voice/live-voice-metrics.ts +472 -0
  835. package/src/live-voice/live-voice-session-manager.ts +222 -0
  836. package/src/live-voice/live-voice-session.ts +1144 -0
  837. package/src/live-voice/live-voice-tts.ts +260 -0
  838. package/src/live-voice/protocol.ts +515 -0
  839. package/src/mcp/client.ts +2 -2
  840. package/src/mcp/manager.ts +0 -5
  841. package/src/media/types.ts +4 -4
  842. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +4 -28
  843. package/src/memory/__tests__/auto-analysis-guard.test.ts +2 -2
  844. package/src/memory/__tests__/conversation-analyze-job.test.ts +7 -62
  845. package/src/memory/__tests__/conversation-group-migration.test.ts +2 -2
  846. package/src/memory/__tests__/find-analysis-conversation.test.ts +2 -1
  847. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  848. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +235 -0
  849. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  850. package/src/memory/admin.ts +65 -7
  851. package/src/memory/app-git-service.ts +0 -46
  852. package/src/memory/app-store.ts +154 -0
  853. package/src/memory/attachments-store.ts +20 -16
  854. package/src/memory/auto-analysis-enqueue.ts +2 -17
  855. package/src/memory/canonical-guardian-store.ts +2 -1
  856. package/src/memory/channel-verification-sessions.ts +1 -1
  857. package/src/memory/checkpoints.ts +1 -1
  858. package/src/memory/context-search/agent-protocol.ts +424 -0
  859. package/src/memory/context-search/agent-runner.ts +1295 -0
  860. package/src/memory/context-search/format.ts +160 -0
  861. package/src/memory/context-search/limits.ts +106 -0
  862. package/src/memory/context-search/search.ts +387 -0
  863. package/src/memory/context-search/sources/conversations.ts +278 -0
  864. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  865. package/src/memory/context-search/sources/memory.ts +95 -0
  866. package/src/memory/context-search/sources/pkb.ts +477 -0
  867. package/src/memory/context-search/sources/workspace.ts +1256 -0
  868. package/src/memory/context-search/types.ts +49 -0
  869. package/src/memory/conversation-analyze-job.ts +3 -24
  870. package/src/memory/conversation-attention-store.ts +1 -1
  871. package/src/memory/conversation-bootstrap.ts +1 -1
  872. package/src/memory/conversation-crud.ts +86 -119
  873. package/src/memory/conversation-directories.ts +1 -11
  874. package/src/memory/conversation-disk-view.ts +1 -5
  875. package/src/memory/conversation-display-order-migration.ts +11 -2
  876. package/src/memory/conversation-group-migration.ts +20 -4
  877. package/src/memory/conversation-key-store.ts +3 -4
  878. package/src/memory/conversation-queries.ts +13 -26
  879. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  880. package/src/memory/conversation-starter-validation.ts +88 -0
  881. package/src/memory/conversation-starters-cadence.ts +1 -1
  882. package/src/memory/conversation-title-service.ts +2 -1
  883. package/src/memory/db-connection.ts +62 -0
  884. package/src/memory/db-init.ts +28 -4
  885. package/src/memory/db-maintenance.ts +1 -1
  886. package/src/memory/delivery-channels.ts +1 -14
  887. package/src/memory/delivery-crud.ts +2 -32
  888. package/src/memory/delivery-status.ts +1 -1
  889. package/src/memory/embedding-backend.ts +3 -21
  890. package/src/memory/embedding-gemini.test.ts +4 -4
  891. package/src/memory/embedding-gemini.ts +0 -2
  892. package/src/memory/embedding-local.ts +6 -6
  893. package/src/memory/embedding-ollama.ts +6 -6
  894. package/src/memory/embedding-openai.ts +6 -6
  895. package/src/memory/embedding-types.ts +21 -0
  896. package/src/memory/external-conversation-store.ts +1 -1
  897. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +408 -0
  898. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +225 -0
  899. package/src/memory/graph/bootstrap.test.ts +2 -7
  900. package/src/memory/graph/bootstrap.ts +2 -1
  901. package/src/memory/graph/capability-seed.ts +3 -3
  902. package/src/memory/graph/compaction.ts +1 -1
  903. package/src/memory/graph/consolidation.ts +13 -10
  904. package/src/memory/graph/conversation-graph-memory.ts +184 -12
  905. package/src/memory/graph/decay.ts +1 -1
  906. package/src/memory/graph/extraction.ts +53 -21
  907. package/src/memory/graph/graph-memory-state-store.ts +1 -1
  908. package/src/memory/graph/graph-search.test.ts +94 -2
  909. package/src/memory/graph/graph-search.ts +22 -7
  910. package/src/memory/graph/image-ref-utils.ts +1 -1
  911. package/src/memory/graph/injection.test.ts +2 -2
  912. package/src/memory/graph/injection.ts +1 -1
  913. package/src/memory/graph/retriever.test.ts +158 -4
  914. package/src/memory/graph/retriever.ts +17 -5
  915. package/src/memory/graph/store.test.ts +2 -1
  916. package/src/memory/graph/store.ts +1 -1
  917. package/src/memory/graph/tool-handlers.ts +73 -247
  918. package/src/memory/graph/tools.ts +35 -53
  919. package/src/memory/group-crud.ts +1 -2
  920. package/src/memory/guardian-action-store.ts +2 -84
  921. package/src/memory/guardian-approvals.ts +1 -49
  922. package/src/memory/guardian-rate-limits.ts +1 -1
  923. package/src/memory/indexer.ts +44 -32
  924. package/src/memory/invite-store.ts +1 -1
  925. package/src/memory/job-handlers/backfill.ts +1 -1
  926. package/src/memory/job-handlers/cleanup.ts +2 -1
  927. package/src/memory/job-handlers/conversation-starters.ts +54 -63
  928. package/src/memory/job-handlers/embedding.test.ts +2 -1
  929. package/src/memory/job-handlers/embedding.ts +1 -1
  930. package/src/memory/job-handlers/index-maintenance.ts +1 -1
  931. package/src/memory/job-handlers/summarization.ts +3 -3
  932. package/src/memory/job-utils.ts +3 -9
  933. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +362 -0
  934. package/src/memory/jobs/embed-concept-page.ts +210 -0
  935. package/src/memory/jobs/embed-pkb-file.test.ts +2 -1
  936. package/src/memory/jobs-store.ts +9 -2
  937. package/src/memory/jobs-worker.ts +56 -17
  938. package/src/memory/lifecycle-events-store.ts +1 -1
  939. package/src/memory/llm-request-log-store.ts +1 -42
  940. package/src/memory/llm-usage-store.ts +130 -44
  941. package/src/memory/media-store.ts +1 -1
  942. package/src/memory/memory-recall-log-store.ts +1 -1
  943. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  944. package/src/memory/migrations/038-actor-token-records.ts +3 -0
  945. package/src/memory/migrations/039-actor-refresh-token-records.ts +3 -0
  946. package/src/memory/migrations/226-schedule-wake-conversation-id.ts +11 -0
  947. package/src/memory/migrations/227-add-conversation-inference-profile.ts +18 -0
  948. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +27 -0
  949. package/src/memory/migrations/229-delete-private-conversations.test.ts +1087 -0
  950. package/src/memory/migrations/229-delete-private-conversations.ts +210 -0
  951. package/src/memory/migrations/230-acp-session-history.ts +41 -0
  952. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +128 -0
  953. package/src/memory/migrations/232-activation-state.ts +38 -0
  954. package/src/memory/migrations/233-document-conversations.ts +54 -0
  955. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  956. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  957. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  958. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  959. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  960. package/src/memory/migrations/index.ts +24 -0
  961. package/src/memory/migrations/registry.ts +31 -0
  962. package/src/memory/pkb/pkb-index.test.ts +4 -5
  963. package/src/memory/pkb/pkb-reconcile.test.ts +4 -5
  964. package/src/memory/pkb/pkb-search.test.ts +83 -3
  965. package/src/memory/pkb/pkb-search.ts +27 -14
  966. package/src/memory/published-pages-store.ts +1 -1
  967. package/src/memory/raw-query.ts +2 -68
  968. package/src/memory/schema/acp.ts +30 -0
  969. package/src/memory/schema/conversations.ts +8 -1
  970. package/src/memory/schema/index.ts +1 -0
  971. package/src/memory/schema/infrastructure.ts +26 -32
  972. package/src/memory/schema/memory-graph.ts +36 -14
  973. package/src/memory/scoped-approval-grants.ts +2 -1
  974. package/src/memory/search/semantic.ts +7 -18
  975. package/src/memory/shared-app-links-store.ts +2 -1
  976. package/src/memory/tool-usage-store.ts +3 -1
  977. package/src/memory/trace-event-store.ts +2 -1
  978. package/src/memory/turn-events-store.ts +1 -1
  979. package/src/memory/usage-buckets.ts +40 -1
  980. package/src/memory/usage-grouped-buckets.ts +127 -0
  981. package/src/memory/v2/__tests__/activation-store.test.ts +202 -0
  982. package/src/memory/v2/__tests__/activation.test.ts +1155 -0
  983. package/src/memory/v2/__tests__/backfill-jobs.test.ts +483 -0
  984. package/src/memory/v2/__tests__/consolidation-job.test.ts +412 -0
  985. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  986. package/src/memory/v2/__tests__/injection.test.ts +1161 -0
  987. package/src/memory/v2/__tests__/migration.test.ts +840 -0
  988. package/src/memory/v2/__tests__/page-store.test.ts +517 -0
  989. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  990. package/src/memory/v2/__tests__/qdrant.test.ts +438 -0
  991. package/src/memory/v2/__tests__/sim.test.ts +549 -0
  992. package/src/memory/v2/__tests__/skill-content.test.ts +85 -0
  993. package/src/memory/v2/__tests__/skill-qdrant.test.ts +657 -0
  994. package/src/memory/v2/__tests__/skill-store.test.ts +463 -0
  995. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  996. package/src/memory/v2/__tests__/sweep-job.test.ts +441 -0
  997. package/src/memory/v2/activation-store.ts +109 -0
  998. package/src/memory/v2/activation.ts +561 -0
  999. package/src/memory/v2/backfill-jobs.ts +357 -0
  1000. package/src/memory/v2/consolidation-job.ts +306 -0
  1001. package/src/memory/v2/edge-index.ts +191 -0
  1002. package/src/memory/v2/injection.ts +431 -0
  1003. package/src/memory/v2/migration.ts +647 -0
  1004. package/src/memory/v2/now-text.ts +37 -0
  1005. package/src/memory/v2/page-store.ts +382 -0
  1006. package/src/memory/v2/prompts/consolidation.ts +261 -0
  1007. package/src/memory/v2/prompts/sweep.ts +56 -0
  1008. package/src/memory/v2/qdrant.ts +342 -0
  1009. package/src/memory/v2/sim.ts +206 -0
  1010. package/src/memory/v2/skill-content.ts +42 -0
  1011. package/src/memory/v2/skill-qdrant.ts +395 -0
  1012. package/src/memory/v2/skill-store.ts +176 -0
  1013. package/src/memory/v2/static-context.ts +62 -0
  1014. package/src/memory/v2/sweep-job.ts +298 -0
  1015. package/src/memory/v2/types.ts +106 -0
  1016. package/src/memory/validation.ts +0 -11
  1017. package/src/messaging/draft-store.ts +0 -6
  1018. package/src/messaging/provider-types.ts +8 -0
  1019. package/src/messaging/provider.ts +7 -0
  1020. package/src/messaging/providers/gmail/client.ts +1 -121
  1021. package/src/messaging/providers/index.ts +262 -0
  1022. package/src/messaging/providers/outlook/client.ts +0 -73
  1023. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  1024. package/src/messaging/providers/slack/adapter.ts +122 -21
  1025. package/src/messaging/providers/slack/api.ts +242 -0
  1026. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  1027. package/src/messaging/providers/slack/backfill.ts +89 -11
  1028. package/src/messaging/providers/slack/client.ts +10 -124
  1029. package/src/messaging/providers/slack/message-metadata.ts +13 -3
  1030. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  1031. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  1032. package/src/messaging/providers/slack/send.ts +383 -0
  1033. package/src/messaging/providers/slack/types.ts +1 -0
  1034. package/src/messaging/providers/telegram-bot/adapter.ts +4 -42
  1035. package/src/messaging/providers/telegram-bot/api.ts +253 -0
  1036. package/src/messaging/providers/telegram-bot/client.ts +17 -58
  1037. package/src/messaging/providers/telegram-bot/send.ts +232 -0
  1038. package/src/messaging/providers/whatsapp/adapter.ts +4 -36
  1039. package/src/messaging/providers/whatsapp/api.ts +319 -0
  1040. package/src/messaging/providers/whatsapp/client.ts +4 -48
  1041. package/src/messaging/providers/whatsapp/send.ts +209 -0
  1042. package/src/notifications/adapters/slack.ts +5 -23
  1043. package/src/notifications/adapters/telegram.ts +8 -29
  1044. package/src/notifications/conversation-candidates.ts +1 -1
  1045. package/src/notifications/conversation-seed-composer.ts +12 -6
  1046. package/src/notifications/copy-composer.ts +1 -1
  1047. package/src/notifications/decision-engine.ts +1 -1
  1048. package/src/notifications/decisions-store.ts +1 -1
  1049. package/src/notifications/deliveries-store.ts +2 -1
  1050. package/src/notifications/deterministic-checks.ts +1 -1
  1051. package/src/notifications/events-store.ts +1 -13
  1052. package/src/notifications/preferences-store.ts +1 -1
  1053. package/src/notifications/signal.ts +0 -9
  1054. package/src/oauth/connection-resolver.test.ts +8 -0
  1055. package/src/oauth/connection-resolver.ts +6 -5
  1056. package/src/oauth/credential-token-resolver.ts +97 -0
  1057. package/src/oauth/manual-token-connection.ts +30 -34
  1058. package/src/oauth/oauth-store.ts +8 -5
  1059. package/src/outbound-proxy/certs.ts +0 -7
  1060. package/src/outbound-proxy/config.ts +0 -74
  1061. package/src/outbound-proxy/health.ts +0 -44
  1062. package/src/outbound-proxy/index.ts +0 -23
  1063. package/src/permissions/approval-policy.test.ts +149 -132
  1064. package/src/permissions/approval-policy.ts +65 -91
  1065. package/src/permissions/approval-provenance.test.ts +184 -0
  1066. package/src/permissions/approval-provenance.ts +70 -0
  1067. package/src/permissions/checker.test.ts +632 -0
  1068. package/src/permissions/checker.ts +270 -460
  1069. package/src/permissions/gateway-threshold-reader.ts +31 -47
  1070. package/src/permissions/ipc-risk-types.ts +95 -0
  1071. package/src/permissions/prompter.ts +13 -11
  1072. package/src/permissions/risk-types.ts +24 -210
  1073. package/src/permissions/secret-prompter.ts +21 -48
  1074. package/src/permissions/types.ts +49 -46
  1075. package/src/permissions/workspace-policy.ts +1 -8
  1076. package/src/platform/sync-identity.ts +0 -8
  1077. package/src/playbooks/playbook-compiler.ts +1 -1
  1078. package/src/plugins/defaults/index.ts +1 -1
  1079. package/src/plugins/defaults/injectors.ts +87 -23
  1080. package/src/plugins/defaults/llm-call.ts +6 -9
  1081. package/src/plugins/defaults/memory-retrieval.ts +1 -6
  1082. package/src/plugins/defaults/overflow-reduce.ts +12 -7
  1083. package/src/plugins/defaults/token-estimate.ts +2 -3
  1084. package/src/plugins/registry.ts +61 -1
  1085. package/src/plugins/types.ts +14 -7
  1086. package/src/plugins/user-loader.ts +36 -10
  1087. package/src/prompts/persona-resolver.ts +2 -4
  1088. package/src/prompts/system-prompt.ts +34 -31
  1089. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  1090. package/src/prompts/templates/SOUL.md +3 -1
  1091. package/src/prompts/update-bulletin-job.ts +2 -0
  1092. package/src/providers/__tests__/provider-env-vars.test.ts +0 -21
  1093. package/src/providers/__tests__/retry-callsite.test.ts +141 -7
  1094. package/src/providers/anthropic/client.ts +143 -52
  1095. package/src/providers/call-site-routing.ts +49 -6
  1096. package/src/providers/fireworks/client.ts +3 -0
  1097. package/src/providers/gemini/client.ts +113 -23
  1098. package/src/providers/managed-proxy/context.ts +0 -17
  1099. package/src/providers/model-catalog.ts +188 -27
  1100. package/src/providers/model-intents.ts +7 -8
  1101. package/src/providers/openai/chat-completions-provider.ts +43 -7
  1102. package/src/providers/openai/responses-provider.ts +46 -5
  1103. package/src/providers/openrouter/client.ts +4 -5
  1104. package/src/providers/provider-env-vars.ts +4 -12
  1105. package/src/providers/provider-send-message.ts +61 -13
  1106. package/src/providers/ratelimit.ts +7 -2
  1107. package/src/providers/registry.ts +15 -10
  1108. package/src/providers/retry.ts +148 -31
  1109. package/src/providers/speech-to-text/openai-whisper-stream.ts +1 -1
  1110. package/src/providers/speech-to-text/openai-whisper.ts +3 -6
  1111. package/src/providers/speech-to-text/provider-catalog.ts +75 -0
  1112. package/src/providers/speech-to-text/xai.ts +5 -5
  1113. package/src/providers/thinking-config.ts +34 -0
  1114. package/src/providers/types.ts +35 -10
  1115. package/src/providers/usage-tracking.ts +96 -0
  1116. package/src/runtime/AGENTS.md +16 -11
  1117. package/src/runtime/__tests__/agent-wake.test.ts +122 -9
  1118. package/src/runtime/__tests__/interactive-ui.test.ts +157 -246
  1119. package/src/runtime/access-request-helper.ts +9 -20
  1120. package/src/runtime/actor-trust-resolver.ts +2 -2
  1121. package/src/runtime/agent-wake.ts +211 -68
  1122. package/src/runtime/approval-conversation-turn.ts +2 -15
  1123. package/src/runtime/approval-message-composer.ts +11 -60
  1124. package/src/runtime/assistant-event-hub.ts +541 -45
  1125. package/src/runtime/assistant-event.ts +16 -69
  1126. package/src/runtime/auth/__tests__/guard-tests.test.ts +6 -30
  1127. package/src/runtime/auth/__tests__/middleware.test.ts +10 -10
  1128. package/src/runtime/auth/__tests__/route-policy.test.ts +0 -8
  1129. package/src/runtime/auth/middleware.ts +5 -5
  1130. package/src/runtime/auth/route-policy.ts +205 -12
  1131. package/src/runtime/auth/token-service.ts +1 -111
  1132. package/src/runtime/capability-tokens.ts +89 -313
  1133. package/src/runtime/channel-approval-types.ts +1 -6
  1134. package/src/runtime/channel-approvals.ts +13 -81
  1135. package/src/runtime/channel-readiness-service.ts +2 -2
  1136. package/src/runtime/channel-reply-delivery.ts +2 -8
  1137. package/src/runtime/channel-retry-sweep.ts +20 -17
  1138. package/src/runtime/channel-verification-service.ts +3 -5
  1139. package/src/runtime/confirmation-request-guardian-bridge.ts +2 -7
  1140. package/src/runtime/gateway-client.ts +37 -378
  1141. package/src/runtime/guardian-action-grant-minter.ts +2 -3
  1142. package/src/runtime/guardian-action-message-composer.ts +11 -52
  1143. package/src/runtime/guardian-action-service.ts +19 -7
  1144. package/src/runtime/guardian-decision-types.ts +4 -65
  1145. package/src/runtime/guardian-reply-router.ts +10 -19
  1146. package/src/runtime/guardian-vellum-migration.ts +5 -64
  1147. package/src/runtime/http-errors.ts +1 -32
  1148. package/src/runtime/http-router.ts +54 -8
  1149. package/src/runtime/http-server.ts +362 -1187
  1150. package/src/runtime/http-types.ts +20 -98
  1151. package/src/runtime/interactive-ui-types.ts +145 -0
  1152. package/src/runtime/interactive-ui.ts +37 -196
  1153. package/src/runtime/invite-redemption-service.ts +1 -1
  1154. package/src/runtime/invite-redemption-templates.ts +1 -1
  1155. package/src/runtime/local-actor-identity.ts +13 -43
  1156. package/src/runtime/message-composer-types.ts +134 -0
  1157. package/src/runtime/middleware/auth.ts +0 -20
  1158. package/src/runtime/middleware/rate-limiter.ts +1 -1
  1159. package/src/runtime/middleware/request-logger.ts +5 -2
  1160. package/src/runtime/migrations/__tests__/job-registry.test.ts +346 -0
  1161. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  1162. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  1163. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  1164. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  1165. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  1166. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  1167. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  1168. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  1169. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +18 -2
  1170. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  1171. package/src/runtime/migrations/job-registry.ts +281 -0
  1172. package/src/runtime/migrations/migration-transport.ts +46 -13
  1173. package/src/runtime/migrations/migration-wizard.ts +2 -2
  1174. package/src/runtime/migrations/origin-mode.ts +40 -0
  1175. package/src/runtime/migrations/vbundle-builder.ts +133 -80
  1176. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  1177. package/src/runtime/migrations/vbundle-importer.ts +8 -8
  1178. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  1179. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -16
  1180. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  1181. package/src/runtime/migrations/vbundle-tar-stream.ts +11 -3
  1182. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  1183. package/src/runtime/nl-approval-parser.ts +16 -21
  1184. package/src/runtime/pending-interactions.ts +42 -16
  1185. package/src/runtime/routes/__tests__/acp-routes.test.ts +394 -0
  1186. package/src/runtime/routes/__tests__/backup-routes.test.ts +232 -339
  1187. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  1188. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +72 -4
  1189. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  1190. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  1191. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  1192. package/src/runtime/routes/__tests__/stt-routes.test.ts +182 -223
  1193. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +230 -0
  1194. package/src/{ipc/__tests__/task-ipc.test.ts → runtime/routes/__tests__/task-routes.test.ts} +116 -96
  1195. package/src/runtime/routes/__tests__/tts-routes.test.ts +185 -289
  1196. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  1197. package/src/runtime/routes/access-request-decision.ts +25 -50
  1198. package/src/runtime/routes/acp-routes.test.ts +368 -0
  1199. package/src/runtime/routes/acp-routes.ts +392 -170
  1200. package/src/runtime/routes/app-management-routes.ts +475 -662
  1201. package/src/runtime/routes/app-routes.ts +192 -177
  1202. package/src/runtime/routes/approval-routes.ts +163 -440
  1203. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +24 -84
  1204. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +3 -10
  1205. package/src/runtime/routes/attachment-routes.ts +409 -253
  1206. package/src/runtime/routes/audio-routes.ts +51 -18
  1207. package/src/runtime/routes/avatar-routes.ts +81 -76
  1208. package/src/runtime/routes/background-tool-routes.ts +94 -0
  1209. package/src/runtime/routes/backup-routes.ts +154 -336
  1210. package/src/runtime/routes/brain-graph-routes.ts +83 -110
  1211. package/src/runtime/routes/browser-routes.ts +127 -0
  1212. package/src/runtime/routes/btw-routes.ts +62 -106
  1213. package/src/runtime/routes/cache-routes.ts +96 -0
  1214. package/src/runtime/routes/call-routes.ts +208 -247
  1215. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +1 -1
  1216. package/src/runtime/routes/channel-delivery-routes.ts +25 -27
  1217. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  1218. package/src/runtime/routes/channel-readiness-routes.ts +79 -120
  1219. package/src/runtime/routes/channel-route-definitions.ts +62 -0
  1220. package/src/runtime/routes/channel-route-shared.ts +15 -45
  1221. package/src/runtime/routes/channel-verification-routes.ts +207 -187
  1222. package/src/runtime/routes/client-routes.ts +81 -0
  1223. package/src/runtime/routes/consolidation-routes.ts +115 -0
  1224. package/src/runtime/routes/contact-routes.ts +533 -407
  1225. package/src/runtime/routes/conversation-analysis-routes.ts +48 -49
  1226. package/src/runtime/routes/conversation-attention-routes.ts +55 -67
  1227. package/src/runtime/routes/conversation-list-routes.ts +248 -0
  1228. package/src/runtime/routes/conversation-management-routes.ts +591 -717
  1229. package/src/runtime/routes/conversation-query-routes.ts +621 -459
  1230. package/src/runtime/routes/conversation-routes.ts +396 -792
  1231. package/src/runtime/routes/conversation-starter-routes.ts +137 -108
  1232. package/src/runtime/routes/credential-prompt-routes.ts +124 -0
  1233. package/src/runtime/routes/debug-routes.ts +34 -39
  1234. package/src/runtime/routes/defer-routes.ts +230 -0
  1235. package/src/runtime/routes/diagnostics-routes.ts +79 -70
  1236. package/src/runtime/routes/documents-routes.ts +163 -117
  1237. package/src/runtime/routes/errors.ts +132 -0
  1238. package/src/runtime/routes/events-routes.ts +126 -119
  1239. package/src/runtime/routes/filing-routes.ts +80 -76
  1240. package/src/runtime/routes/global-search-routes.ts +51 -57
  1241. package/src/runtime/routes/group-routes.ts +199 -181
  1242. package/src/runtime/routes/guardian-action-routes.ts +100 -171
  1243. package/src/runtime/routes/guardian-approval-interception.ts +27 -58
  1244. package/src/runtime/routes/guardian-approval-prompt.ts +10 -21
  1245. package/src/runtime/routes/guardian-approval-reply-helpers.ts +2 -6
  1246. package/src/runtime/routes/guardian-expiry-sweep.ts +19 -36
  1247. package/src/runtime/routes/heartbeat-routes.ts +194 -209
  1248. package/src/runtime/routes/home-feed-routes.ts +85 -187
  1249. package/src/runtime/routes/home-state-routes.ts +27 -24
  1250. package/src/runtime/routes/host-bash-routes.ts +45 -54
  1251. package/src/runtime/routes/host-browser-routes.ts +44 -99
  1252. package/src/runtime/routes/host-cu-routes.ts +80 -71
  1253. package/src/runtime/routes/host-file-routes.ts +53 -62
  1254. package/src/runtime/routes/host-transfer-routes.ts +216 -0
  1255. package/src/runtime/routes/http-adapter.ts +172 -0
  1256. package/src/runtime/routes/identity-routes.ts +161 -85
  1257. package/src/runtime/routes/inbound-conversation.ts +11 -18
  1258. package/src/runtime/routes/inbound-message-handler.ts +639 -232
  1259. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +81 -226
  1260. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +2 -3
  1261. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -90
  1262. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +25 -50
  1263. package/src/runtime/routes/inbound-stages/edit-intercept.ts +7 -7
  1264. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
  1265. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +5 -6
  1266. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -24
  1267. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -10
  1268. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
  1269. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +3 -3
  1270. package/src/runtime/routes/index.ts +201 -0
  1271. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +25 -32
  1272. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +22 -31
  1273. package/src/runtime/routes/integrations/slack/channel.ts +50 -71
  1274. package/src/runtime/routes/integrations/slack/share.ts +49 -58
  1275. package/src/runtime/routes/integrations/telegram.ts +91 -74
  1276. package/src/runtime/routes/integrations/twilio.ts +163 -240
  1277. package/src/runtime/routes/integrations/vercel.ts +57 -54
  1278. package/src/runtime/routes/interface-routes.ts +43 -0
  1279. package/src/runtime/routes/internal-oauth-routes.ts +56 -0
  1280. package/src/runtime/routes/internal-twilio-routes.ts +46 -0
  1281. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  1282. package/src/runtime/routes/llm-context-normalization.ts +4 -2
  1283. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  1284. package/src/runtime/routes/log-export-routes.ts +90 -100
  1285. package/src/runtime/routes/memory-item-routes.test.ts +152 -175
  1286. package/src/runtime/routes/memory-item-routes.ts +243 -323
  1287. package/src/runtime/routes/memory-v2-routes.ts +188 -0
  1288. package/src/runtime/routes/migration-rollback-routes.ts +167 -212
  1289. package/src/runtime/routes/migration-routes.ts +1037 -377
  1290. package/src/runtime/routes/notification-routes.ts +199 -70
  1291. package/src/runtime/routes/oauth-apps.ts +254 -251
  1292. package/src/runtime/routes/oauth-providers.ts +66 -57
  1293. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +60 -120
  1294. package/src/runtime/routes/playground/__tests__/guard.test.ts +34 -54
  1295. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +107 -151
  1296. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +41 -117
  1297. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +95 -138
  1298. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +115 -217
  1299. package/src/runtime/routes/playground/__tests__/state.test.ts +41 -90
  1300. package/src/runtime/routes/playground/conversation-not-found.ts +9 -11
  1301. package/src/runtime/routes/playground/force-compact.ts +41 -54
  1302. package/src/runtime/routes/playground/guard.ts +18 -19
  1303. package/src/runtime/routes/playground/helpers.ts +103 -0
  1304. package/src/runtime/routes/playground/index.ts +15 -27
  1305. package/src/runtime/routes/playground/inject-failures.ts +48 -64
  1306. package/src/runtime/routes/playground/reset-circuit.ts +31 -57
  1307. package/src/runtime/routes/playground/seed-conversation.ts +66 -92
  1308. package/src/runtime/routes/playground/seeded-conversations.ts +60 -64
  1309. package/src/runtime/routes/playground/state.ts +23 -24
  1310. package/src/runtime/routes/profiler-routes.ts +132 -167
  1311. package/src/runtime/routes/ps-routes.ts +120 -0
  1312. package/src/runtime/routes/recording-routes.ts +189 -270
  1313. package/src/runtime/routes/rename-conversation-routes.ts +85 -0
  1314. package/src/runtime/routes/schedule-routes.ts +239 -246
  1315. package/src/runtime/routes/secret-routes.ts +305 -282
  1316. package/src/runtime/routes/secrets-deps.ts +24 -0
  1317. package/src/runtime/routes/settings-routes.ts +370 -449
  1318. package/src/runtime/routes/skills-routes.ts +417 -471
  1319. package/src/runtime/routes/stt-routes.ts +196 -206
  1320. package/src/runtime/routes/subagents-routes.ts +125 -141
  1321. package/src/runtime/routes/suggest-trust-rule-routes.ts +275 -0
  1322. package/src/runtime/routes/surface-action-routes.ts +135 -190
  1323. package/src/runtime/routes/surface-content-routes.ts +84 -118
  1324. package/src/runtime/routes/task-routes.ts +354 -0
  1325. package/src/runtime/routes/telemetry-routes.ts +33 -49
  1326. package/src/runtime/routes/trace-event-routes.ts +55 -74
  1327. package/src/runtime/routes/trust-rules-routes.ts +61 -244
  1328. package/src/runtime/routes/tts-routes.ts +187 -169
  1329. package/src/runtime/routes/types.ts +139 -0
  1330. package/src/{ipc/routes/ui-request.ts → runtime/routes/ui-request-routes.ts} +23 -17
  1331. package/src/runtime/routes/upgrade-broadcast-routes.ts +150 -198
  1332. package/src/runtime/routes/usage-routes.ts +222 -171
  1333. package/src/runtime/routes/user-routes.ts +88 -18
  1334. package/src/runtime/routes/wake-conversation-routes.ts +49 -0
  1335. package/src/{ipc/routes/watcher.ts → runtime/routes/watcher-routes.ts} +84 -39
  1336. package/src/runtime/routes/wipe-conversation-routes.ts +89 -0
  1337. package/src/runtime/routes/work-items-routes.test.ts +10 -20
  1338. package/src/runtime/routes/work-items-routes.ts +419 -437
  1339. package/src/runtime/routes/workspace-commit-routes.ts +30 -61
  1340. package/src/runtime/routes/workspace-routes.test.ts +254 -381
  1341. package/src/runtime/routes/workspace-routes.ts +238 -246
  1342. package/src/runtime/runtime-mode.ts +8 -1
  1343. package/src/runtime/services/__tests__/analyze-conversation.test.ts +82 -120
  1344. package/src/runtime/services/analyze-conversation.ts +18 -55
  1345. package/src/runtime/services/conversation-serializer.ts +179 -0
  1346. package/src/runtime/trust-context-resolver.ts +3 -2
  1347. package/src/runtime/verification-outbound-actions.ts +14 -50
  1348. package/src/runtime/verification-rate-limiter.ts +1 -1
  1349. package/src/schedule/schedule-store.ts +64 -18
  1350. package/src/schedule/scheduler.ts +101 -0
  1351. package/src/security/ces-credential-client.ts +32 -169
  1352. package/src/security/ces-rpc-credential-backend.ts +1 -1
  1353. package/src/security/credential-backend.ts +6 -6
  1354. package/src/security/oauth-completion-page.ts +1 -1
  1355. package/src/security/oauth2.ts +3 -6
  1356. package/src/security/secret-scanner.ts +14 -547
  1357. package/src/security/secure-keys.ts +31 -11
  1358. package/src/security/token-manager.ts +7 -3
  1359. package/src/sequence/analytics.ts +1 -1
  1360. package/src/sequence/guardrails.ts +3 -3
  1361. package/src/sequence/store.ts +2 -1
  1362. package/src/signals/bash.ts +1 -1
  1363. package/src/signals/cancel.ts +16 -25
  1364. package/src/signals/conversation-undo.ts +2 -27
  1365. package/src/signals/emit-event.ts +1 -2
  1366. package/src/signals/event-stream.ts +1 -1
  1367. package/src/signals/user-message.ts +108 -22
  1368. package/src/skills/catalog-cache.ts +7 -0
  1369. package/src/skills/catalog-files.ts +0 -5
  1370. package/src/skills/catalog-install.ts +29 -18
  1371. package/src/skills/category-inference.ts +0 -11
  1372. package/src/skills/clawhub.ts +4 -4
  1373. package/src/skills/inline-command-runner.ts +1 -7
  1374. package/src/skills/managed-store.ts +2 -2
  1375. package/src/skills/remote-skill-policy.ts +6 -7
  1376. package/src/subagent/index.ts +2 -6
  1377. package/src/subagent/manager.ts +94 -107
  1378. package/src/subagent/types.ts +9 -0
  1379. package/src/tasks/SPEC.md +2 -2
  1380. package/src/tasks/task-compiler.ts +1 -1
  1381. package/src/tasks/task-runner.ts +2 -22
  1382. package/src/tasks/task-store.ts +2 -29
  1383. package/src/telemetry/types.ts +6 -0
  1384. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  1385. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  1386. package/src/tools/acp/list-agents.test.ts +115 -0
  1387. package/src/tools/acp/list-agents.ts +31 -0
  1388. package/src/tools/acp/spawn.test.ts +378 -0
  1389. package/src/tools/acp/spawn.ts +142 -62
  1390. package/src/tools/acp/steer.test.ts +100 -0
  1391. package/src/tools/acp/steer.ts +38 -0
  1392. package/src/tools/background-tool-registry.ts +98 -0
  1393. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  1394. package/src/tools/browser/browser-execution.ts +38 -127
  1395. package/src/tools/browser/browser-manager.ts +1 -8
  1396. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  1397. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +1 -1
  1398. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +3 -1
  1399. package/src/tools/browser/cdp-client/factory.ts +48 -76
  1400. package/src/tools/browser/cdp-client/index.ts +1 -14
  1401. package/src/tools/browser/cdp-client/types.ts +4 -1
  1402. package/src/tools/computer-use/definitions.ts +1 -1
  1403. package/src/tools/credential-execution/make-authenticated-request.ts +2 -2
  1404. package/src/tools/credential-execution/manage-secure-command-tool.ts +1 -1
  1405. package/src/tools/credential-execution/run-authenticated-command.ts +2 -2
  1406. package/src/tools/credentials/broker-types.ts +2 -1
  1407. package/src/tools/document/editor-template.ts +1 -1
  1408. package/src/tools/execution-timeout.ts +1 -1
  1409. package/src/tools/executor.ts +53 -45
  1410. package/src/tools/host-filesystem/edit.ts +3 -2
  1411. package/src/tools/host-filesystem/read.ts +3 -2
  1412. package/src/tools/host-filesystem/transfer.test.ts +271 -0
  1413. package/src/tools/host-filesystem/transfer.ts +235 -0
  1414. package/src/tools/host-filesystem/write.ts +3 -2
  1415. package/src/tools/host-terminal/host-shell.ts +192 -13
  1416. package/src/tools/mcp/mcp-tool-factory.ts +1 -1
  1417. package/src/tools/memory/register.test.ts +161 -1
  1418. package/src/tools/memory/register.ts +19 -34
  1419. package/src/tools/network/script-proxy/index.ts +1 -10
  1420. package/src/tools/permission-checker.ts +84 -220
  1421. package/src/tools/policy-context.ts +1 -8
  1422. package/src/tools/registry.ts +16 -1
  1423. package/src/tools/shared/shell-output.ts +4 -1
  1424. package/src/tools/side-effects.ts +2 -2
  1425. package/src/tools/skills/execute.ts +1 -1
  1426. package/src/tools/skills/sandbox-runner.ts +1 -6
  1427. package/src/tools/skills/skill-tool-factory.ts +32 -0
  1428. package/src/tools/subagent/spawn.ts +35 -11
  1429. package/src/tools/terminal/safe-env.ts +10 -1
  1430. package/src/tools/terminal/shell.ts +142 -88
  1431. package/src/tools/tool-approval-handler.ts +4 -70
  1432. package/src/tools/tool-input-summary.ts +10 -0
  1433. package/src/tools/types.ts +136 -183
  1434. package/src/tools/ui-surface/definitions.ts +2 -2
  1435. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  1436. package/src/tts/provider-catalog.ts +1 -1
  1437. package/src/usage/actors.ts +2 -1
  1438. package/src/usage/attribution.ts +185 -0
  1439. package/src/usage/pricing.ts +166 -0
  1440. package/src/usage/types.ts +14 -0
  1441. package/src/util/debounce.ts +0 -21
  1442. package/src/util/errors.ts +0 -8
  1443. package/src/util/json.ts +13 -0
  1444. package/src/util/log-redact.ts +0 -1
  1445. package/src/util/logger.ts +3 -3
  1446. package/src/util/platform.ts +85 -124
  1447. package/src/util/pricing.ts +158 -8
  1448. package/src/watcher/engine.ts +42 -20
  1449. package/src/watcher/watcher-store.ts +2 -1
  1450. package/src/work-items/work-item-runner.ts +15 -42
  1451. package/src/work-items/work-item-store.ts +1 -1
  1452. package/src/workspace/git-service.ts +1 -6
  1453. package/src/workspace/migrations/006-services-config.ts +10 -1
  1454. package/src/workspace/migrations/017-seed-persona-dirs.ts +1 -1
  1455. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +1 -1
  1456. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +1 -1
  1457. package/src/workspace/migrations/031-drop-user-md.ts +1 -1
  1458. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +3 -4
  1459. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  1460. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +150 -0
  1461. package/src/workspace/migrations/053-release-notes-acp-codex.ts +107 -0
  1462. package/src/workspace/migrations/054-seed-recall-callsite.ts +102 -0
  1463. package/src/workspace/migrations/055-release-notes-agentic-recall.ts +63 -0
  1464. package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +65 -0
  1465. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +98 -0
  1466. package/src/workspace/migrations/058-release-notes-acp-sessions-ui.ts +71 -0
  1467. package/src/workspace/migrations/059-move-pid-to-workspace.ts +53 -0
  1468. package/src/workspace/migrations/060-memory-v2-init.ts +37 -0
  1469. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  1470. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  1471. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  1472. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  1473. package/src/workspace/migrations/rebuild-conversation-disk-view.ts +1 -1
  1474. package/src/workspace/migrations/registry.ts +26 -0
  1475. package/src/workspace/migrations/runner.ts +2 -2
  1476. package/src/workspace/provider-commit-message-generator.ts +4 -4
  1477. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +0 -471
  1478. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +0 -436
  1479. package/src/__tests__/cli-command-risk-guard.test.ts +0 -368
  1480. package/src/__tests__/config-watcher-feature-flags.test.ts +0 -211
  1481. package/src/__tests__/conversation-approval-overrides.test.ts +0 -207
  1482. package/src/__tests__/conversation-host-access-routes.test.ts +0 -229
  1483. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +0 -226
  1484. package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +0 -167
  1485. package/src/__tests__/ephemeral-permissions.test.ts +0 -474
  1486. package/src/__tests__/extension-id-sync-guard.test.ts +0 -241
  1487. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +0 -374
  1488. package/src/__tests__/native-host-marker-sync-guard.test.ts +0 -157
  1489. package/src/__tests__/pairing-concurrent.test.ts +0 -84
  1490. package/src/__tests__/pairing-routes.test.ts +0 -181
  1491. package/src/__tests__/parser.test.ts +0 -595
  1492. package/src/__tests__/permission-checker-host-gate.test.ts +0 -488
  1493. package/src/__tests__/permission-controls-v2-flag.test.ts +0 -55
  1494. package/src/__tests__/permission-mode.test.ts +0 -89
  1495. package/src/__tests__/provider-env-vars-scope.test.ts +0 -52
  1496. package/src/__tests__/risk-classifier-parity.test.ts +0 -230
  1497. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  1498. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  1499. package/src/__tests__/secret-detection-handler.test.ts +0 -74
  1500. package/src/__tests__/secret-scanner-executor.test.ts +0 -451
  1501. package/src/__tests__/shell-identity.test.ts +0 -236
  1502. package/src/__tests__/shell-parser-fuzz.test.ts +0 -629
  1503. package/src/__tests__/shell-parser-property.test.ts +0 -936
  1504. package/src/__tests__/starter-bundle.test.ts +0 -173
  1505. package/src/__tests__/stt-catalog-parity.test.ts +0 -282
  1506. package/src/__tests__/task-runner.test.ts +0 -224
  1507. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  1508. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  1509. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -354
  1510. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  1511. package/src/__tests__/trust-store-pattern-matches.test.ts +0 -29
  1512. package/src/__tests__/trust-store.test.ts +0 -2013
  1513. package/src/__tests__/v2-consent-policy.test.ts +0 -103
  1514. package/src/browser/identifiers.ts +0 -51
  1515. package/src/cli/db.ts +0 -1
  1516. package/src/config/bundled-skills/settings/tools/avatar-get.ts +0 -40
  1517. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +0 -64
  1518. package/src/config/bundled-skills/settings/tools/avatar-update.ts +0 -88
  1519. package/src/context/__tests__/microcompact.test.ts +0 -805
  1520. package/src/context/microcompact.ts +0 -443
  1521. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +0 -127
  1522. package/src/daemon/approved-devices-store.ts +0 -110
  1523. package/src/daemon/external-skills-bootstrap.ts +0 -41
  1524. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  1525. package/src/daemon/message-types/trust.ts +0 -71
  1526. package/src/daemon/pairing-store.ts +0 -229
  1527. package/src/events/tool-notification-listener.ts +0 -17
  1528. package/src/ipc/cli-server.ts +0 -252
  1529. package/src/ipc/routes/attachment.ts +0 -114
  1530. package/src/ipc/routes/browser-context.ts +0 -63
  1531. package/src/ipc/routes/browser.ts +0 -97
  1532. package/src/ipc/routes/cache.ts +0 -96
  1533. package/src/ipc/routes/get-contact.ts +0 -16
  1534. package/src/ipc/routes/index.ts +0 -35
  1535. package/src/ipc/routes/list-clients.ts +0 -31
  1536. package/src/ipc/routes/merge-contacts.ts +0 -17
  1537. package/src/ipc/routes/notification.ts +0 -133
  1538. package/src/ipc/routes/rename-conversation.ts +0 -59
  1539. package/src/ipc/routes/search-contacts.ts +0 -19
  1540. package/src/ipc/routes/task-queue.ts +0 -226
  1541. package/src/ipc/routes/task.ts +0 -173
  1542. package/src/ipc/routes/upsert-contact.ts +0 -25
  1543. package/src/ipc/routes/wake-conversation.ts +0 -19
  1544. package/src/memory/db.ts +0 -23
  1545. package/src/permissions/arg-parser.test.ts +0 -161
  1546. package/src/permissions/arg-parser.ts +0 -141
  1547. package/src/permissions/bash-risk-classifier.test.ts +0 -1620
  1548. package/src/permissions/bash-risk-classifier.ts +0 -950
  1549. package/src/permissions/command-registry.test.ts +0 -774
  1550. package/src/permissions/command-registry.ts +0 -1005
  1551. package/src/permissions/defaults.ts +0 -314
  1552. package/src/permissions/file-risk-classifier.test.ts +0 -535
  1553. package/src/permissions/file-risk-classifier.ts +0 -274
  1554. package/src/permissions/permission-mode.ts +0 -24
  1555. package/src/permissions/schedule-risk-classifier.test.ts +0 -129
  1556. package/src/permissions/schedule-risk-classifier.ts +0 -85
  1557. package/src/permissions/shell-identity.ts +0 -297
  1558. package/src/permissions/skill-risk-classifier.test.ts +0 -311
  1559. package/src/permissions/skill-risk-classifier.ts +0 -214
  1560. package/src/permissions/trust-client.ts +0 -359
  1561. package/src/permissions/trust-store-interface.ts +0 -100
  1562. package/src/permissions/trust-store.ts +0 -1330
  1563. package/src/permissions/v2-consent-policy.ts +0 -87
  1564. package/src/permissions/web-risk-classifier.test.ts +0 -170
  1565. package/src/permissions/web-risk-classifier.ts +0 -89
  1566. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +0 -715
  1567. package/src/runtime/__tests__/capability-tokens.test.ts +0 -258
  1568. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  1569. package/src/runtime/__tests__/client-registry.test.ts +0 -293
  1570. package/src/runtime/actor-refresh-token-store.ts +0 -156
  1571. package/src/runtime/actor-token-store.ts +0 -207
  1572. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -264
  1573. package/src/runtime/auth/credential-service.ts +0 -352
  1574. package/src/runtime/chrome-extension-registry.ts +0 -368
  1575. package/src/runtime/client-registry.ts +0 -261
  1576. package/src/runtime/conversation-approval-overrides.ts +0 -86
  1577. package/src/runtime/routes/browser-extension-pair-routes.ts +0 -575
  1578. package/src/runtime/routes/channel-routes.ts +0 -112
  1579. package/src/runtime/routes/contact-routes.test.ts +0 -298
  1580. package/src/runtime/routes/guardian-bootstrap-routes.ts +0 -175
  1581. package/src/runtime/routes/guardian-refresh-routes.ts +0 -79
  1582. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -336
  1583. package/src/runtime/routes/invite-routes.ts +0 -280
  1584. package/src/runtime/routes/pairing-routes.ts +0 -431
  1585. package/src/runtime/routes/playground/deps.ts +0 -56
  1586. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +0 -67
  1587. package/src/runtime/services/analyze-deps-singleton.ts +0 -32
  1588. package/src/tasks/ephemeral-permissions.ts +0 -55
  1589. package/src/tools/secret-detection-handler.ts +0 -359
  1590. package/src/tools/terminal/backends/native.ts +0 -327
  1591. package/src/tools/terminal/backends/types.ts +0 -37
  1592. package/src/tools/terminal/parser.ts +0 -623
  1593. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  1594. package/src/tools/terminal/sandbox.ts +0 -40
  1595. package/src/types/qrcode.d.ts +0 -13
  1596. package/src/util/network-info.ts +0 -55
  1597. /package/node_modules/@vellumai/{ces-contracts → ces-client}/tsconfig.json +0 -0
  1598. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/grants.test.ts +0 -0
  1599. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/error.ts +0 -0
  1600. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/grants.ts +0 -0
  1601. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/handles.ts +0 -0
  1602. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rendering.ts +0 -0
  1603. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rpc.ts +0 -0
@@ -5,16 +5,6 @@
5
5
  * configured port (default: 7821).
6
6
  */
7
7
 
8
- import {
9
- existsSync,
10
- mkdirSync,
11
- readFileSync,
12
- renameSync,
13
- unlinkSync,
14
- writeFileSync,
15
- } from "node:fs";
16
- import { dirname, resolve } from "node:path";
17
-
18
8
  import type { ServerWebSocket } from "bun";
19
9
 
20
10
  import {
@@ -35,75 +25,36 @@ import {
35
25
  handleStatusCallback,
36
26
  handleVoiceWebhook,
37
27
  } from "../calls/twilio-routes.js";
38
- import { parseChannelId } from "../channels/types.js";
39
- import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
40
- import {
41
- getGatewayInternalBaseUrl,
42
- hasUngatedHttpAuthDisabled,
43
- isHttpAuthDisabled,
44
- } from "../config/env.js";
28
+ import { isHttpAuthDisabled } from "../config/env.js";
29
+ import { getIsPlatform } from "../config/env-registry.js";
45
30
  import { getConfig } from "../config/loader.js";
46
- import type { ServerMessage } from "../daemon/message-protocol.js";
47
- import { PairingStore } from "../daemon/pairing-store.js";
31
+ import { processMessage } from "../daemon/process-message.js";
32
+ import { createLiveVoiceSession } from "../live-voice/live-voice-session.js";
33
+ import { LiveVoiceSessionManager } from "../live-voice/live-voice-session-manager.js";
48
34
  import {
49
- type AttentionState,
50
- type Confidence,
51
- getAttentionStateByConversationIds,
52
- markConversationUnread,
53
- recordConversationSeenSignal,
54
- type SignalType,
55
- } from "../memory/conversation-attention-store.js";
56
- import {
57
- addMessage,
58
- type ConversationRow,
59
- createConversation,
60
- deleteConversation,
61
- forkConversation as forkConversationInStore,
62
- getConversation,
63
- getDisplayMetaForConversations,
64
- } from "../memory/conversation-crud.js";
65
- import { resolveConversationId } from "../memory/conversation-key-store.js";
66
- import {
67
- countConversations,
68
- listConversations,
69
- listConversationsByTitlePrefix,
70
- listPinnedConversations,
71
- } from "../memory/conversation-queries.js";
72
- import type { ExternalConversationBinding } from "../memory/external-conversation-store.js";
73
- import * as externalConversationStore from "../memory/external-conversation-store.js";
74
- import { listGroups } from "../memory/group-crud.js";
75
- import { enqueueMemoryJob } from "../memory/jobs-store.js";
35
+ type LiveVoiceClientFrame,
36
+ type LiveVoiceProtocolError,
37
+ LiveVoiceProtocolErrorCode,
38
+ type LiveVoiceServerFrame,
39
+ parseLiveVoiceBinaryAudioFrame,
40
+ parseLiveVoiceClientTextFrame,
41
+ } from "../live-voice/protocol.js";
76
42
  import { resolveStreamingTranscriber } from "../providers/speech-to-text/resolve.js";
77
- import {
78
- consumeCallback,
79
- consumeCallbackError,
80
- } from "../security/oauth-callback-registry.js";
81
43
  import {
82
44
  activeSttStreamSessions,
83
45
  SttStreamSession,
84
46
  } from "../stt/stt-stream-session.js";
85
- import { UserError } from "../util/errors.js";
86
47
  import { getLogger } from "../util/logger.js";
87
- import { getRuntimePortFilePath } from "../util/platform.js";
88
- import { buildAssistantEvent } from "./assistant-event.js";
89
- import { assistantEventHub } from "./assistant-event-hub.js";
90
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "./assistant-scope.js";
91
48
  // Auth
92
49
  import {
93
50
  authenticateHostBrowserResultRequest,
94
51
  authenticateRequest,
95
52
  } from "./auth/middleware.js";
96
53
  import { parseSub } from "./auth/subject.js";
97
- import {
98
- mintDaemonDeliveryToken,
99
- mintUiPageToken,
100
- verifyToken,
101
- } from "./auth/token-service.js";
54
+ import { verifyToken } from "./auth/token-service.js";
102
55
  import { verifyHostBrowserCapability } from "./capability-tokens.js";
103
56
  import { sweepFailedEvents } from "./channel-retry-sweep.js";
104
- import { getChromeExtensionRegistry } from "./chrome-extension-registry.js";
105
- import { httpError } from "./http-errors.js";
106
- import type { RouteDefinition } from "./http-router.js";
57
+ import { httpError, type HttpErrorCode } from "./http-errors.js";
107
58
  import { HttpRouter } from "./http-router.js";
108
59
  // Middleware
109
60
  import {
@@ -129,111 +80,23 @@ import {
129
80
  TWILIO_WEBHOOK_RE,
130
81
  validateTwilioWebhook,
131
82
  } from "./middleware/twilio-validation.js";
132
- import { acpRouteDefinitions } from "./routes/acp-routes.js";
133
- import { appManagementRouteDefinitions } from "./routes/app-management-routes.js";
134
- import { handleServePage } from "./routes/app-routes.js";
135
- import { appRouteDefinitions } from "./routes/app-routes.js";
136
- import { approvalRouteDefinitions } from "./routes/approval-routes.js";
137
- import { attachmentRouteDefinitions } from "./routes/attachment-routes.js";
138
- import { handleGetAudio } from "./routes/audio-routes.js";
139
- import { avatarRouteDefinitions } from "./routes/avatar-routes.js";
140
- import { backupRouteDefinitions } from "./routes/backup-routes.js";
141
- import { brainGraphRouteDefinitions } from "./routes/brain-graph-routes.js";
142
- import { handleBrowserExtensionPair } from "./routes/browser-extension-pair-routes.js";
143
- import { btwRouteDefinitions } from "./routes/btw-routes.js";
144
- import { callRouteDefinitions } from "./routes/call-routes.js";
83
+ import { ROUTES as APP_ROUTES } from "./routes/app-routes.js";
84
+ import { ROUTES as AUDIO_ROUTES } from "./routes/audio-routes.js";
145
85
  import {
146
86
  startCanonicalGuardianExpirySweep,
147
87
  stopCanonicalGuardianExpirySweep,
148
88
  } from "./routes/canonical-guardian-expiry-sweep.js";
149
- import { channelReadinessRouteDefinitions } from "./routes/channel-readiness-routes.js";
150
89
  import {
151
- channelRouteDefinitions,
152
90
  startGuardianExpirySweep,
153
91
  stopGuardianExpirySweep,
154
- } from "./routes/channel-routes.js";
155
- import { channelVerificationRouteDefinitions } from "./routes/channel-verification-routes.js";
156
- import {
157
- contactCatchAllRouteDefinitions,
158
- contactRouteDefinitions,
159
- } from "./routes/contact-routes.js";
160
- import { conversationAnalysisRouteDefinitions } from "./routes/conversation-analysis-routes.js";
161
- import { conversationAttentionRouteDefinitions } from "./routes/conversation-attention-routes.js";
162
- import {
163
- type ConversationManagementDeps,
164
- conversationManagementRouteDefinitions,
165
- } from "./routes/conversation-management-routes.js";
166
- import { conversationQueryRouteDefinitions } from "./routes/conversation-query-routes.js";
167
- import { conversationRouteDefinitions } from "./routes/conversation-routes.js";
168
- import { conversationStarterRouteDefinitions } from "./routes/conversation-starter-routes.js";
169
- import { debugRouteDefinitions } from "./routes/debug-routes.js";
170
- import { diagnosticsRouteDefinitions } from "./routes/diagnostics-routes.js";
171
- import { documentRouteDefinitions } from "./routes/documents-routes.js";
172
- import { eventsRouteDefinitions } from "./routes/events-routes.js";
173
- import { filingRouteDefinitions } from "./routes/filing-routes.js";
174
- import { globalSearchRouteDefinitions } from "./routes/global-search-routes.js";
175
- import { groupRouteDefinitions } from "./routes/group-routes.js";
176
- import { guardianActionRouteDefinitions } from "./routes/guardian-action-routes.js";
177
- import { handleGuardianBootstrap } from "./routes/guardian-bootstrap-routes.js";
178
- import { handleGuardianRefresh } from "./routes/guardian-refresh-routes.js";
179
- import { heartbeatRouteDefinitions } from "./routes/heartbeat-routes.js";
180
- import { homeFeedRouteDefinitions } from "./routes/home-feed-routes.js";
181
- import { homeStateRouteDefinitions } from "./routes/home-state-routes.js";
182
- import { hostBashRouteDefinitions } from "./routes/host-bash-routes.js";
92
+ } from "./routes/channel-guardian-routes.js";
93
+ import { RouteError } from "./routes/errors.js";
183
94
  import {
184
- hostBrowserRouteDefinitions,
185
95
  resolveHostBrowserEvent,
186
96
  resolveHostBrowserResultByRequestId,
187
97
  resolveHostBrowserSessionInvalidated,
188
98
  } from "./routes/host-browser-routes.js";
189
- import { hostCuRouteDefinitions } from "./routes/host-cu-routes.js";
190
- import { hostFileRouteDefinitions } from "./routes/host-file-routes.js";
191
- import {
192
- handleHealth,
193
- handleReadyz,
194
- identityRouteDefinitions,
195
- } from "./routes/identity-routes.js";
196
- import { slackChannelRouteDefinitions } from "./routes/integrations/slack/channel.js";
197
- import { slackShareRouteDefinitions } from "./routes/integrations/slack/share.js";
198
- import { telegramRouteDefinitions } from "./routes/integrations/telegram.js";
199
- import { twilioRouteDefinitions } from "./routes/integrations/twilio.js";
200
- import { vercelRouteDefinitions } from "./routes/integrations/vercel.js";
201
- import { inviteRouteDefinitions } from "./routes/invite-routes.js";
202
- import { logExportRouteDefinitions } from "./routes/log-export-routes.js";
203
- import { memoryItemRouteDefinitions } from "./routes/memory-item-routes.js";
204
- import { migrationRollbackRouteDefinitions } from "./routes/migration-rollback-routes.js";
205
- import { migrationRouteDefinitions } from "./routes/migration-routes.js";
206
- import { notificationRouteDefinitions } from "./routes/notification-routes.js";
207
- import { oauthAppsRouteDefinitions } from "./routes/oauth-apps.js";
208
- import { oauthProvidersRouteDefinitions } from "./routes/oauth-providers.js";
209
- import type { PairingHandlerContext } from "./routes/pairing-routes.js";
210
- import {
211
- handlePairingRequest,
212
- handlePairingStatus,
213
- pairingRouteDefinitions,
214
- } from "./routes/pairing-routes.js";
215
- import { playgroundRouteDefinitions } from "./routes/playground/index.js";
216
- import { profilerRouteDefinitions } from "./routes/profiler-routes.js";
217
- import { recordingRouteDefinitions } from "./routes/recording-routes.js";
218
- import { scheduleRouteDefinitions } from "./routes/schedule-routes.js";
219
- import { secretRouteDefinitions } from "./routes/secret-routes.js";
220
- import { settingsRouteDefinitions } from "./routes/settings-routes.js";
221
- import { skillRouteDefinitions } from "./routes/skills-routes.js";
222
- import { sttRouteDefinitions } from "./routes/stt-routes.js";
223
- import { subagentRouteDefinitions } from "./routes/subagents-routes.js";
224
- import { surfaceActionRouteDefinitions } from "./routes/surface-action-routes.js";
225
- import { surfaceContentRouteDefinitions } from "./routes/surface-content-routes.js";
226
- import { telemetryRouteDefinitions } from "./routes/telemetry-routes.js";
227
- import { traceEventRouteDefinitions } from "./routes/trace-event-routes.js";
228
- import { trustRulesRouteDefinitions } from "./routes/trust-rules-routes.js";
229
- import { ttsRouteDefinitions } from "./routes/tts-routes.js";
230
- import { upgradeBroadcastRouteDefinitions } from "./routes/upgrade-broadcast-routes.js";
231
- import { usageRouteDefinitions } from "./routes/usage-routes.js";
232
- import { userRouteDefinitions } from "./routes/user-routes.js";
233
- import { workItemRouteDefinitions } from "./routes/work-items-routes.js";
234
- import { workspaceCommitRouteDefinitions } from "./routes/workspace-commit-routes.js";
235
- import { workspaceRouteDefinitions } from "./routes/workspace-routes.js";
236
- import { setAnalysisDeps } from "./services/analyze-deps-singleton.js";
99
+ import { handleHealth, handleReadyz } from "./routes/identity-routes.js";
237
100
  import { matchSkillRoute } from "./skill-route-registry.js";
238
101
 
239
102
  // Re-export for consumers
@@ -249,7 +112,6 @@ export type {
249
112
  RuntimeAttachmentMetadata,
250
113
  RuntimeHttpServerOptions,
251
114
  RuntimeMessageConversationOptions,
252
- SendMessageDeps,
253
115
  } from "./http-types.js";
254
116
 
255
117
  import type {
@@ -257,9 +119,7 @@ import type {
257
119
  ApprovalCopyGenerator,
258
120
  GuardianActionCopyGenerator,
259
121
  GuardianFollowUpConversationGenerator,
260
- MessageProcessor,
261
122
  RuntimeHttpServerOptions,
262
- SendMessageDeps,
263
123
  } from "./http-types.js";
264
124
 
265
125
  const log = getLogger("runtime-http");
@@ -273,9 +133,8 @@ const MAX_REQUEST_BODY_BYTES = 512 * 1024 * 1024;
273
133
  /**
274
134
  * WebSocket data attached to `/v1/browser-relay` connections. The route
275
135
  * is used exclusively by the chrome-extension CDP proxy — outbound
276
- * `host_browser_request` frames are pushed through the
277
- * {@link ChromeExtensionRegistry}, and inbound `host_browser_result`
278
- * frames are dispatched through
136
+ * `host_browser_request` frames are pushed through the assistant event
137
+ * hub, and inbound `host_browser_result` frames are dispatched through
279
138
  * `resolveHostBrowserResultByRequestId`. The extension may also submit
280
139
  * results via `POST /v1/host-browser-result` (both transports resolve
281
140
  * through the same core function).
@@ -285,21 +144,16 @@ interface BrowserRelayWebSocketData {
285
144
  connectionId: string;
286
145
  /**
287
146
  * Guardian identity derived from the JWT claims at WebSocket upgrade
288
- * time. Used by the ChromeExtensionRegistry to route
289
- * host_browser_request frames to the correct extension. Undefined when
290
- * HTTP auth is disabled (dev bypass) or when the token's sub cannot be
291
- * parsed into an actor principal.
147
+ * time. Undefined when HTTP auth is disabled (dev bypass) or when the
148
+ * token's sub cannot be parsed into an actor principal.
292
149
  */
293
150
  guardianId?: string;
294
151
  /**
295
152
  * Stable per-extension-install identifier supplied by the client on
296
153
  * the WebSocket handshake (via the `clientInstanceId` query param or
297
- * the `x-client-instance-id` header). Plumbed into the
298
- * ChromeExtensionRegistry so multiple parallel installs for the same
299
- * guardian (e.g. two Chrome profiles, two desktops) don't evict each
300
- * other on register/unregister. Undefined on older extension builds
301
- * — the registry synthesizes a connection-scoped fallback key in
302
- * that case for backwards-compatible single-instance semantics.
154
+ * the `x-client-instance-id` header). Allows multiple parallel installs
155
+ * for the same guardian (e.g. two Chrome profiles, two desktops) to
156
+ * coexist. Undefined on older extension builds.
303
157
  */
304
158
  clientInstanceId?: string;
305
159
  }
@@ -338,60 +192,45 @@ interface SttStreamWebSocketData {
338
192
  session?: SttStreamSession;
339
193
  }
340
194
 
195
+ /**
196
+ * WebSocket data attached to `/v1/live-voice` connections. The `wsType`
197
+ * discriminator routes frames to the live voice protocol shell instead of
198
+ * the other WebSocket handlers.
199
+ */
200
+ interface LiveVoiceWebSocketData {
201
+ wsType: "live-voice";
202
+ sessionId?: string;
203
+ lastSeq: number;
204
+ }
205
+
341
206
  export class RuntimeHttpServer {
342
207
  private server: ReturnType<typeof Bun.serve> | null = null;
343
208
  private port: number;
344
209
  private hostname: string;
345
- /** Legacy shared secret for pairing routes (not used for delivery or auth). */
346
- private bearerToken: string | undefined;
347
- private processMessage?: MessageProcessor;
210
+
348
211
  private approvalCopyGenerator?: ApprovalCopyGenerator;
349
212
  private approvalConversationGenerator?: ApprovalConversationGenerator;
350
213
  private guardianActionCopyGenerator?: GuardianActionCopyGenerator;
351
214
  private guardianFollowUpConversationGenerator?: GuardianFollowUpConversationGenerator;
352
- private interfacesDir: string | null;
353
- private suggestionCache = new Map<string, string>();
354
- private suggestionInFlight = new Map<string, Promise<string | null>>();
355
215
  private retrySweepTimer: ReturnType<typeof setInterval> | null = null;
356
216
  private sweepInProgress = false;
357
- private pairingStore = new PairingStore();
358
- private pairingBroadcast?: (msg: ServerMessage) => void;
359
- private sendMessageDeps?: SendMessageDeps;
360
- private findConversation?: RuntimeHttpServerOptions["findConversation"];
361
- private findConversationBySurfaceId?: RuntimeHttpServerOptions["findConversationBySurfaceId"];
362
- private getSkillContext?: RuntimeHttpServerOptions["getSkillContext"];
363
- private conversationManagementDeps?: RuntimeHttpServerOptions["conversationManagementDeps"];
364
- private getModelSetContext?: RuntimeHttpServerOptions["getModelSetContext"];
365
- private getRecordingDeps?: RuntimeHttpServerOptions["getRecordingDeps"];
366
- private getCesClient?: RuntimeHttpServerOptions["getCesClient"];
367
- private onProviderCredentialsChanged?: RuntimeHttpServerOptions["onProviderCredentialsChanged"];
368
- private getHeartbeatService?: RuntimeHttpServerOptions["getHeartbeatService"];
369
- private getFilingService?: RuntimeHttpServerOptions["getFilingService"];
217
+
218
+ private readonly liveVoiceSessionManager: LiveVoiceSessionManager;
370
219
  private router: HttpRouter;
371
220
 
372
221
  constructor(options: RuntimeHttpServerOptions = {}) {
373
222
  this.port = options.port ?? DEFAULT_PORT;
374
223
  this.hostname = options.hostname ?? DEFAULT_HOSTNAME;
375
- this.bearerToken = options.bearerToken;
376
- this.processMessage = options.processMessage;
224
+
377
225
  this.approvalCopyGenerator = options.approvalCopyGenerator;
378
226
  this.approvalConversationGenerator = options.approvalConversationGenerator;
379
227
  this.guardianActionCopyGenerator = options.guardianActionCopyGenerator;
380
228
  this.guardianFollowUpConversationGenerator =
381
229
  options.guardianFollowUpConversationGenerator;
382
- this.interfacesDir = options.interfacesDir ?? null;
383
- this.sendMessageDeps = options.sendMessageDeps;
384
- this.findConversation = options.findConversation;
385
- this.findConversationBySurfaceId = options.findConversationBySurfaceId;
386
- this.getSkillContext = options.getSkillContext;
387
- this.conversationManagementDeps = options.conversationManagementDeps;
388
- this.getModelSetContext = options.getModelSetContext;
389
- this.getRecordingDeps = options.getRecordingDeps;
390
- this.getCesClient = options.getCesClient;
391
- this.onProviderCredentialsChanged = options.onProviderCredentialsChanged;
392
- this.getHeartbeatService = options.getHeartbeatService;
393
- this.getFilingService = options.getFilingService;
394
- this.router = new HttpRouter(this.buildRouteTable());
230
+ this.liveVoiceSessionManager = new LiveVoiceSessionManager({
231
+ createSession: (context) => createLiveVoiceSession(context),
232
+ });
233
+ this.router = new HttpRouter();
395
234
  }
396
235
 
397
236
  /** The port the server is actually listening on (resolved after start). */
@@ -399,40 +238,13 @@ export class RuntimeHttpServer {
399
238
  return this.server?.port ?? this.port;
400
239
  }
401
240
 
402
- /** Expose the pairing store so the daemon server can wire HTTP handlers. */
403
- getPairingStore(): PairingStore {
404
- return this.pairingStore;
405
- }
406
-
407
- /** Set a callback for broadcasting server messages (wired by daemon server). */
408
- setPairingBroadcast(fn: (msg: ServerMessage) => void): void {
409
- this.pairingBroadcast = fn;
410
- }
411
-
412
- private get pairingContext(): PairingHandlerContext {
413
- const broadcast = this.pairingBroadcast;
414
- return {
415
- pairingStore: this.pairingStore,
416
- bearerToken: this.bearerToken,
417
- pairingBroadcast: broadcast
418
- ? (msg) => {
419
- // Broadcast to all clients via the event hub so HTTP/SSE clients
420
- // (e.g. macOS app) receive pairing approval requests.
421
- broadcast(msg);
422
- void assistantEventHub.publish(
423
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, msg),
424
- );
425
- }
426
- : undefined,
427
- };
428
- }
429
-
430
241
  async start(): Promise<void> {
431
242
  type AllWebSocketData =
432
243
  | RelayWebSocketData
433
244
  | BrowserRelayWebSocketData
434
245
  | MediaStreamWebSocketData
435
- | SttStreamWebSocketData;
246
+ | SttStreamWebSocketData
247
+ | LiveVoiceWebSocketData;
436
248
  this.server = Bun.serve<AllWebSocketData>({
437
249
  port: this.port,
438
250
  hostname: this.hostname,
@@ -440,25 +252,8 @@ export class RuntimeHttpServer {
440
252
  maxRequestBodySize: MAX_REQUEST_BODY_BYTES,
441
253
  fetch: (req, server) => this.handleRequest(req, server),
442
254
  websocket: {
443
- open(ws) {
255
+ open: (ws) => {
444
256
  const data = ws.data as AllWebSocketData;
445
- if ("wsType" in data && data.wsType === "browser-relay") {
446
- // When the JWT sub resolved to a guardian principal at upgrade
447
- // time, register this connection with the chrome-extension
448
- // registry so host_browser_request frames can be routed to it.
449
- if (data.guardianId) {
450
- const now = Date.now();
451
- getChromeExtensionRegistry().register({
452
- id: data.connectionId,
453
- guardianId: data.guardianId,
454
- clientInstanceId: data.clientInstanceId,
455
- ws,
456
- connectedAt: now,
457
- lastActiveAt: now,
458
- });
459
- }
460
- return;
461
- }
462
257
  if ("wsType" in data && data.wsType === "media-stream") {
463
258
  const msData = data as MediaStreamWebSocketData;
464
259
  log.info(
@@ -547,6 +342,10 @@ export class RuntimeHttpServer {
547
342
  );
548
343
  return;
549
344
  }
345
+ if ("wsType" in data && data.wsType === "live-voice") {
346
+ log.info("Live voice WebSocket opened");
347
+ return;
348
+ }
550
349
  const callSessionId = (data as RelayWebSocketData).callSessionId;
551
350
  log.info({ callSessionId }, "ConversationRelay WebSocket opened");
552
351
  if (callSessionId) {
@@ -557,7 +356,7 @@ export class RuntimeHttpServer {
557
356
  activeRelayConnections.set(callSessionId, connection);
558
357
  }
559
358
  },
560
- message(ws, message) {
359
+ message: (ws, message) => {
561
360
  const data = ws.data as AllWebSocketData;
562
361
  const raw =
563
362
  typeof message === "string"
@@ -670,11 +469,7 @@ export class RuntimeHttpServer {
670
469
  return;
671
470
  }
672
471
  case "keepalive": {
673
- // Extension keepalive frames refresh the connection's
674
- // activity timestamp without producing log noise or
675
- // altering routing semantics. Unknown extra keys on
676
- // the frame are silently ignored (lenient validation).
677
- getChromeExtensionRegistry().touch(data.connectionId);
472
+ // Extension keepalive acknowledged, no action needed.
678
473
  return;
679
474
  }
680
475
  default: {
@@ -708,23 +503,33 @@ export class RuntimeHttpServer {
708
503
  }
709
504
  return;
710
505
  }
506
+ if ("wsType" in data && data.wsType === "live-voice") {
507
+ void this.handleLiveVoiceMessage(
508
+ ws as ServerWebSocket<LiveVoiceWebSocketData>,
509
+ message,
510
+ ).catch((err) => {
511
+ log.warn(
512
+ { error: err instanceof Error ? err.message : String(err) },
513
+ "Live voice WebSocket message handler failed",
514
+ );
515
+ this.sendLiveVoiceError(
516
+ ws as ServerWebSocket<LiveVoiceWebSocketData>,
517
+ {
518
+ code: LiveVoiceProtocolErrorCode.InvalidFrame,
519
+ message: "Live voice frame handling failed",
520
+ },
521
+ );
522
+ });
523
+ return;
524
+ }
711
525
  const callSessionId = (data as RelayWebSocketData).callSessionId;
712
526
  if (callSessionId) {
713
527
  const connection = activeRelayConnections.get(callSessionId);
714
528
  connection?.handleMessage(raw);
715
529
  }
716
530
  },
717
- close(ws, code, reason) {
531
+ close: (ws, code, reason) => {
718
532
  const data = ws.data as AllWebSocketData;
719
- if ("wsType" in data && data.wsType === "browser-relay") {
720
- // Always attempt to unregister — the registry uses connectionId
721
- // as the key and no-ops if the entry is absent (e.g. when the
722
- // connection was never registered because guardianId was
723
- // undefined, or when it was superseded by a newer registration
724
- // for the same guardian).
725
- getChromeExtensionRegistry().unregister(data.connectionId);
726
- return;
727
- }
728
533
  if ("wsType" in data && data.wsType === "media-stream") {
729
534
  const msData = data as MediaStreamWebSocketData;
730
535
  log.info(
@@ -775,6 +580,18 @@ export class RuntimeHttpServer {
775
580
  }
776
581
  return;
777
582
  }
583
+ if ("wsType" in data && data.wsType === "live-voice") {
584
+ log.info(
585
+ {
586
+ sessionId: data.sessionId,
587
+ code,
588
+ reason: reason?.toString(),
589
+ },
590
+ "Live voice WebSocket closed",
591
+ );
592
+ this.releaseLiveVoiceSession(data, "websocket_close");
593
+ return;
594
+ }
778
595
  const callSessionId = (data as RelayWebSocketData).callSessionId;
779
596
  log.info(
780
597
  { callSessionId, code, reason: reason?.toString() },
@@ -801,31 +618,25 @@ export class RuntimeHttpServer {
801
618
  );
802
619
  }
803
620
 
804
- this.pairingStore.start();
805
-
806
- if (hasUngatedHttpAuthDisabled()) {
807
- log.warn(
808
- "DISABLE_HTTP_AUTH is set but VELLUM_UNSAFE_AUTH_BYPASS=1 is not — auth bypass is IGNORED and HTTP authentication remains enabled. Set VELLUM_UNSAFE_AUTH_BYPASS=1 to confirm the bypass.",
809
- );
810
- } else if (isHttpAuthDisabled()) {
811
- log.warn(
812
- "DISABLE_HTTP_AUTH is set — HTTP API authentication is DISABLED. All API endpoints are accessible without a bearer token. Do not use in production.",
813
- );
621
+ if (isHttpAuthDisabled()) {
622
+ if (getIsPlatform()) {
623
+ log.info(
624
+ "DISABLE_HTTP_AUTH is set — HTTP auth disabled (expected: platform handles auth)",
625
+ );
626
+ } else {
627
+ log.warn(
628
+ "DISABLE_HTTP_AUTH is set — HTTP API authentication is DISABLED. All API endpoints are accessible without a bearer token.",
629
+ );
630
+ }
814
631
  }
815
632
 
816
633
  log.info(
817
634
  {
818
635
  port: this.actualPort,
819
636
  hostname: this.hostname,
820
- auth: !!this.bearerToken,
821
637
  },
822
638
  "Runtime HTTP server listening",
823
639
  );
824
-
825
- // Advertise the actual port to thin helpers that need to reach the
826
- // runtime without inheriting the daemon's environment (e.g. the
827
- // chrome-extension native messaging helper, spawned by Chrome).
828
- this.writeRuntimePortFile(this.actualPort);
829
640
  }
830
641
 
831
642
  /**
@@ -834,108 +645,27 @@ export class RuntimeHttpServer {
834
645
  * Extracted from start() to allow future callers to defer sweep startup.
835
646
  */
836
647
  private startBackgroundSweeps(): void {
837
- if (this.processMessage && !this.retrySweepTimer) {
838
- const pm = this.processMessage;
839
- const mintBt = () => mintDaemonDeliveryToken();
648
+ if (!this.retrySweepTimer) {
840
649
  this.retrySweepTimer = setInterval(() => {
841
650
  if (this.sweepInProgress) return;
842
651
  this.sweepInProgress = true;
843
- sweepFailedEvents(pm, mintBt).finally(() => {
652
+ sweepFailedEvents(processMessage).finally(() => {
844
653
  this.sweepInProgress = false;
845
654
  });
846
655
  }, 30_000);
847
656
  }
848
657
 
849
- startGuardianExpirySweep(
850
- getGatewayInternalBaseUrl(),
851
- () => mintDaemonDeliveryToken(),
852
- this.approvalCopyGenerator,
853
- );
658
+ startGuardianExpirySweep(this.approvalCopyGenerator);
854
659
  log.info("Guardian approval expiry sweep started");
855
660
 
856
- startGuardianActionSweep(
857
- getGatewayInternalBaseUrl(),
858
- () => mintDaemonDeliveryToken(),
859
- this.guardianActionCopyGenerator,
860
- );
661
+ startGuardianActionSweep(this.guardianActionCopyGenerator);
861
662
  log.info("Guardian action expiry sweep started");
862
663
 
863
664
  startCanonicalGuardianExpirySweep();
864
665
  log.info("Canonical guardian request expiry sweep started");
865
666
  }
866
667
 
867
- /**
868
- * Atomically publish the runtime HTTP port to ~/.vellum/runtime-port so
869
- * external helpers can locate a non-default `RUNTIME_HTTP_PORT` without
870
- * any manifest changes. Best-effort — write failures never block
871
- * daemon startup (see assistant/AGENTS.md "Daemon startup philosophy").
872
- */
873
- private writeRuntimePortFile(actualPort: number): void {
874
- try {
875
- const portFile = getRuntimePortFilePath();
876
- const dir = dirname(portFile);
877
- if (!existsSync(dir)) {
878
- mkdirSync(dir, { recursive: true });
879
- }
880
- const tmpPath = `${portFile}.tmp.${process.pid}`;
881
- writeFileSync(tmpPath, String(actualPort), { mode: 0o644 });
882
- renameSync(tmpPath, portFile);
883
- log.info({ portFile, actualPort }, "Wrote runtime port file");
884
- } catch (err) {
885
- log.warn(
886
- { err },
887
- "Failed to write runtime port file; non-default assistant ports may require --assistant-port on thin helpers",
888
- );
889
- }
890
- }
891
-
892
- /**
893
- * Remove the runtime port file written by `writeRuntimePortFile`.
894
- * Called from `stop()` on clean shutdown so a stale file does not
895
- * point thin helpers (e.g. the chrome-extension native messaging
896
- * helper) at a dead port until the next daemon start overwrites it.
897
- * Best-effort — unlink failures never block shutdown.
898
- *
899
- * The unlink is conditional: we only remove the file if its current
900
- * contents still match this server's port. The runtime-port file
901
- * lives at the user-home level (`~/.vellum/runtime-port`) and is
902
- * therefore shared across multiple daemon instances running on
903
- * different `RUNTIME_HTTP_PORT`s. If a sibling instance has already
904
- * rewritten the file with its own port, deleting it would strand
905
- * thin helpers on the default port `7821` and break their ability
906
- * to reach the still-running sibling.
907
- *
908
- * Note: this only runs on graceful shutdown. A crash leaves the
909
- * file in place; the next successful startup overwrites it.
910
- */
911
- private removeRuntimePortFile(): void {
912
- try {
913
- const portFile = getRuntimePortFilePath();
914
- if (!existsSync(portFile)) return;
915
- // Read-then-compare-then-unlink. Race-safe enough: the worst case
916
- // is that another instance writes the file between our read and
917
- // our unlink, in which case we erroneously delete its mapping.
918
- // That window is short (a few microseconds) and a sibling startup
919
- // will rewrite the file on its next port-publish call. The much
920
- // more common multi-instance race — sibling already overwrote
921
- // before our stop() runs — is correctly handled here as a no-op.
922
- const current = readFileSync(portFile, "utf-8").trim();
923
- if (current !== String(this.actualPort)) {
924
- log.info(
925
- { portFile, current, actualPort: this.actualPort },
926
- "Leaving runtime port file alone — owned by another instance",
927
- );
928
- return;
929
- }
930
- unlinkSync(portFile);
931
- log.info({ portFile }, "Removed runtime port file");
932
- } catch (err) {
933
- log.warn({ err }, "Failed to remove runtime port file");
934
- }
935
- }
936
-
937
668
  async stop(): Promise<void> {
938
- this.pairingStore.stop();
939
669
  stopGuardianExpirySweep();
940
670
  stopGuardianActionSweep();
941
671
  stopCanonicalGuardianExpirySweep();
@@ -952,12 +682,19 @@ export class RuntimeHttpServer {
952
682
  activeSttStreamSessions.delete(sessionId);
953
683
  }
954
684
 
685
+ const liveVoiceSessionId = this.liveVoiceSessionManager.activeSessionId;
686
+ if (liveVoiceSessionId) {
687
+ await this.liveVoiceSessionManager.releaseSession(
688
+ liveVoiceSessionId,
689
+ "manager_shutdown",
690
+ );
691
+ }
692
+
955
693
  if (this.server) {
956
694
  this.server.stop(true);
957
695
  this.server = null;
958
696
  log.info("Runtime HTTP server stopped");
959
697
  }
960
- this.removeRuntimePortFile();
961
698
  }
962
699
 
963
700
  private async handleRequest(
@@ -1026,43 +763,48 @@ export class RuntimeHttpServer {
1026
763
  return this.handleSttStreamUpgrade(req, server);
1027
764
  }
1028
765
 
766
+ // WebSocket upgrade for live voice — same private-network restrictions
767
+ // and gateway-service token verification as STT streaming.
768
+ if (
769
+ path === "/v1/live-voice" &&
770
+ req.headers.get("upgrade")?.toLowerCase() === "websocket"
771
+ ) {
772
+ return this.handleLiveVoiceUpgrade(req, server);
773
+ }
774
+
1029
775
  // Twilio webhook endpoints — before auth check because Twilio
1030
776
  // webhook POSTs don't include bearer tokens.
1031
777
  const twilioResponse = await this.handleTwilioWebhook(req, path);
1032
778
  if (twilioResponse) return twilioResponse;
1033
779
 
1034
780
  // Audio serving endpoint — before auth check because Twilio
1035
- // fetches these URLs directly. The audioId is an unguessable UUID.
781
+ // fetches these URLs directly (isPublic route, ATL-314).
1036
782
  const audioMatch = path.match(/^\/v1\/audio\/([^/]+)$/);
1037
783
  if (audioMatch && req.method === "GET") {
1038
- return handleGetAudio(audioMatch[1]);
1039
- }
1040
-
1041
- // Pairing endpoints (unauthenticated, secret-gated)
1042
- if (path === "/v1/pairing/request" && req.method === "POST") {
1043
- return await handlePairingRequest(req, this.pairingContext);
1044
- }
1045
- if (path === "/v1/pairing/status" && req.method === "GET") {
1046
- return handlePairingStatus(url, this.pairingContext);
1047
- }
1048
-
1049
- // Chrome extension capability-token pair endpoint — unauthenticated but
1050
- // restricted to loopback peers + an extension-id allowlist. Used by the
1051
- // native messaging helper to bootstrap a scoped token.
1052
- if (path === "/v1/browser-extension-pair") {
1053
- return await handleBrowserExtensionPair(req, server);
1054
- }
1055
-
1056
- // Guardian bootstrap and refresh endpoints — before JWT auth because
1057
- // bootstrap is the first endpoint called to obtain a JWT, and refresh
1058
- // needs to work when the access token is expired. Bootstrap has its
1059
- // own loopback IP validation; refresh is secured by the refresh token
1060
- // in the request body (32 random bytes, hash-only storage).
1061
- if (path === "/v1/guardian/init" && req.method === "POST") {
1062
- return await handleGuardianBootstrap(req, server);
1063
- }
1064
- if (path === "/v1/guardian/refresh" && req.method === "POST") {
1065
- return await handleGuardianRefresh(req);
784
+ const audioDef = AUDIO_ROUTES.find((r) => r.operationId === "audio_get")!;
785
+ const args = { pathParams: { audioId: audioMatch[1] } };
786
+ try {
787
+ const result = await audioDef.handler(args);
788
+ const headers =
789
+ typeof audioDef.responseHeaders === "function"
790
+ ? audioDef.responseHeaders(args)
791
+ : audioDef.responseHeaders;
792
+ if (result instanceof ReadableStream) {
793
+ return new Response(result as ReadableStream<Uint8Array>, {
794
+ headers,
795
+ });
796
+ }
797
+ return new Response(result as BodyInit, { headers });
798
+ } catch (err) {
799
+ if (err instanceof RouteError) {
800
+ return httpError(
801
+ err.code as HttpErrorCode,
802
+ err.message,
803
+ err.statusCode,
804
+ );
805
+ }
806
+ throw err;
807
+ }
1066
808
  }
1067
809
 
1068
810
  // Skill-registered routes (e.g. meet-bot event ingress). Handled before
@@ -1092,7 +834,7 @@ export class RuntimeHttpServer {
1092
834
  const normalizedPath = path.endsWith("/") ? path.slice(0, -1) : path;
1093
835
  const authResult =
1094
836
  normalizedPath === "/v1/host-browser-result" && req.method === "POST"
1095
- ? authenticateHostBrowserResultRequest(req)
837
+ ? await authenticateHostBrowserResultRequest(req)
1096
838
  : authenticateRequest(req);
1097
839
  if (!authResult.ok) {
1098
840
  return authResult.response;
@@ -1102,9 +844,18 @@ export class RuntimeHttpServer {
1102
844
  // Serve shareable app pages (outside /v1/ namespace, no rate limiting)
1103
845
  const pagesMatch = path.match(/^\/pages\/([^/]+)$/);
1104
846
  if (pagesMatch && req.method === "GET") {
1105
- return withErrorHandling("pages", async () =>
1106
- handleServePage(pagesMatch[1]),
1107
- );
847
+ return withErrorHandling("pages", async () => {
848
+ const pageDef = APP_ROUTES.find(
849
+ (r) => r.operationId === "pages_serve",
850
+ )!;
851
+ const args = { pathParams: { appId: pagesMatch[1] } };
852
+ const body = pageDef.handler(args) as string;
853
+ const headers =
854
+ typeof pageDef.responseHeaders === "function"
855
+ ? pageDef.responseHeaders(args)
856
+ : pageDef.responseHeaders;
857
+ return new Response(body, { headers });
858
+ });
1108
859
  }
1109
860
 
1110
861
  // Per-client-IP rate limiting for /v1/* endpoints. Authenticated requests
@@ -1166,10 +917,10 @@ export class RuntimeHttpServer {
1166
917
  return routerResponse ?? httpError("NOT_FOUND", "Not found", 404);
1167
918
  }
1168
919
 
1169
- private handleBrowserRelayUpgrade(
920
+ private async handleBrowserRelayUpgrade(
1170
921
  req: Request,
1171
922
  server: ReturnType<typeof Bun.serve>,
1172
- ): Response {
923
+ ): Promise<Response> {
1173
924
  if (
1174
925
  !isLoopbackHost(new URL(req.url).hostname) &&
1175
926
  !isPrivateNetworkPeer(server, req)
@@ -1185,8 +936,8 @@ export class RuntimeHttpServer {
1185
936
  // `/v1/browser-relay` handshake:
1186
937
  //
1187
938
  // 1. **Capability token** — a signed `host_browser_command`
1188
- // capability minted by `mintHostBrowserCapability()` and handed
1189
- // to the chrome extension by the native-messaging pair flow
939
+ // capability minted by the gateway and handed to the chrome
940
+ // extension by the native-messaging pair flow
1190
941
  // (`/v1/browser-extension-pair`). This is the preferred,
1191
942
  // self-hosted default: the extension never has to touch a
1192
943
  // gateway JWT.
@@ -1235,7 +986,7 @@ export class RuntimeHttpServer {
1235
986
  // messaging pair flow. We derive `guardianId` from the
1236
987
  // capability claims directly — the claims are HMAC-signed by
1237
988
  // the same daemon so there is no cross-tenant risk.
1238
- const capabilityClaims = verifyHostBrowserCapability(token);
989
+ const capabilityClaims = await verifyHostBrowserCapability(token);
1239
990
  if (capabilityClaims) {
1240
991
  guardianId = capabilityClaims.guardianId;
1241
992
  } else {
@@ -1266,9 +1017,7 @@ export class RuntimeHttpServer {
1266
1017
  guardianId = fallbackGuardianId;
1267
1018
  } else {
1268
1019
  // Fail closed: a service-token relay upgrade without a
1269
- // guardian context cannot be routed safely. Allowing the
1270
- // upgrade to proceed creates an unscoped socket that never
1271
- // registers in the ChromeExtensionRegistry.
1020
+ // guardian context cannot be routed safely.
1272
1021
  log.warn(
1273
1022
  {
1274
1023
  principalType: subResult.ok
@@ -1304,6 +1053,28 @@ export class RuntimeHttpServer {
1304
1053
  return undefined!;
1305
1054
  }
1306
1055
 
1056
+ private verifyGatewayServiceToken(req: Request): Response | null {
1057
+ if (isHttpAuthDisabled()) return null;
1058
+
1059
+ const wsUrl = new URL(req.url);
1060
+ const token = wsUrl.searchParams.get("token");
1061
+ if (!token) {
1062
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
1063
+ }
1064
+
1065
+ const jwtResult = verifyToken(token, "vellum-daemon");
1066
+ if (!jwtResult.ok) {
1067
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
1068
+ }
1069
+
1070
+ const subResult = parseSub(jwtResult.claims.sub);
1071
+ if (!subResult.ok || subResult.principalType !== "svc_gateway") {
1072
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
1073
+ }
1074
+
1075
+ return null;
1076
+ }
1077
+
1307
1078
  private handleRelayUpgrade(
1308
1079
  req: Request,
1309
1080
  server: ReturnType<typeof Bun.serve>,
@@ -1316,6 +1087,10 @@ export class RuntimeHttpServer {
1316
1087
  );
1317
1088
  }
1318
1089
 
1090
+ // Verify the gateway service token before accepting the upgrade.
1091
+ const tokenError = this.verifyGatewayServiceToken(req);
1092
+ if (tokenError) return tokenError;
1093
+
1319
1094
  const wsUrl = new URL(req.url);
1320
1095
  const callSessionId = wsUrl.searchParams.get("callSessionId");
1321
1096
  if (!callSessionId) {
@@ -1341,6 +1116,10 @@ export class RuntimeHttpServer {
1341
1116
  );
1342
1117
  }
1343
1118
 
1119
+ // Verify the gateway service token before accepting the upgrade.
1120
+ const tokenError = this.verifyGatewayServiceToken(req);
1121
+ if (tokenError) return tokenError;
1122
+
1344
1123
  const wsUrl = new URL(req.url);
1345
1124
  const callSessionId = wsUrl.searchParams.get("callSessionId");
1346
1125
  if (!callSessionId) {
@@ -1382,23 +1161,8 @@ export class RuntimeHttpServer {
1382
1161
  }
1383
1162
 
1384
1163
  // Verify the gateway service token before accepting the upgrade.
1385
- if (!isHttpAuthDisabled()) {
1386
- const wsUrl = new URL(req.url);
1387
- const token = wsUrl.searchParams.get("token");
1388
- if (!token) {
1389
- return httpError("UNAUTHORIZED", "Unauthorized", 401);
1390
- }
1391
- const jwtResult = verifyToken(token, "vellum-daemon");
1392
- if (!jwtResult.ok) {
1393
- return httpError("UNAUTHORIZED", "Unauthorized", 401);
1394
- }
1395
- // Accept gateway service tokens (svc:gateway:*) — these are the
1396
- // only tokens the gateway mints for upstream connections.
1397
- const subResult = parseSub(jwtResult.claims.sub);
1398
- if (!subResult.ok || subResult.principalType !== "svc_gateway") {
1399
- return httpError("UNAUTHORIZED", "Unauthorized", 401);
1400
- }
1401
- }
1164
+ const tokenError = this.verifyGatewayServiceToken(req);
1165
+ if (tokenError) return tokenError;
1402
1166
 
1403
1167
  const wsUrl = new URL(req.url);
1404
1168
  // provider is optional compatibility metadata — the runtime resolves
@@ -1431,6 +1195,175 @@ export class RuntimeHttpServer {
1431
1195
  return undefined!;
1432
1196
  }
1433
1197
 
1198
+ /**
1199
+ * Handle WebSocket upgrade for `/v1/live-voice`.
1200
+ *
1201
+ * The gateway owns downstream client auth and forwards this upstream with
1202
+ * a short-lived gateway service token. The runtime accepts only private
1203
+ * network peers/origins so the shell is not publicly reachable.
1204
+ */
1205
+ private handleLiveVoiceUpgrade(
1206
+ req: Request,
1207
+ server: ReturnType<typeof Bun.serve>,
1208
+ ): Response {
1209
+ if (!isPrivateNetworkPeer(server, req) || !isPrivateNetworkOrigin(req)) {
1210
+ return httpError(
1211
+ "FORBIDDEN",
1212
+ "Direct live voice access disabled — only private network peers allowed",
1213
+ 403,
1214
+ );
1215
+ }
1216
+
1217
+ const tokenError = this.verifyGatewayServiceToken(req);
1218
+ if (tokenError) return tokenError;
1219
+
1220
+ const upgraded = server.upgrade(req, {
1221
+ data: {
1222
+ wsType: "live-voice",
1223
+ lastSeq: 0,
1224
+ } satisfies LiveVoiceWebSocketData,
1225
+ });
1226
+ if (!upgraded) {
1227
+ return new Response("WebSocket upgrade failed", { status: 500 });
1228
+ }
1229
+ return undefined!;
1230
+ }
1231
+
1232
+ private async handleLiveVoiceMessage(
1233
+ ws: ServerWebSocket<LiveVoiceWebSocketData>,
1234
+ message: string | ArrayBuffer | ArrayBufferView,
1235
+ ): Promise<void> {
1236
+ if (typeof message === "string") {
1237
+ const result = parseLiveVoiceClientTextFrame(message);
1238
+ if (!result.ok) {
1239
+ this.sendLiveVoiceError(ws, result.error);
1240
+ return;
1241
+ }
1242
+ await this.dispatchLiveVoiceClientFrame(ws, result.frame);
1243
+ return;
1244
+ }
1245
+
1246
+ const result = parseLiveVoiceBinaryAudioFrame(message);
1247
+ if (!result.ok) {
1248
+ this.sendLiveVoiceError(ws, result.error);
1249
+ return;
1250
+ }
1251
+
1252
+ const sessionId = ws.data.sessionId;
1253
+ if (!sessionId) {
1254
+ this.sendLiveVoiceStateError(
1255
+ ws,
1256
+ "Live voice binary audio received before start",
1257
+ );
1258
+ return;
1259
+ }
1260
+
1261
+ const handled = await this.liveVoiceSessionManager.handleBinaryAudio(
1262
+ sessionId,
1263
+ result.frame.data,
1264
+ );
1265
+ if (handled.status === "not_found") {
1266
+ ws.data.sessionId = undefined;
1267
+ this.sendLiveVoiceStateError(ws, "Live voice session is not active");
1268
+ }
1269
+ }
1270
+
1271
+ private async dispatchLiveVoiceClientFrame(
1272
+ ws: ServerWebSocket<LiveVoiceWebSocketData>,
1273
+ frame: LiveVoiceClientFrame,
1274
+ ): Promise<void> {
1275
+ if (frame.type === "start") {
1276
+ if (ws.data.sessionId) {
1277
+ this.sendLiveVoiceStateError(ws, "Live voice session already started");
1278
+ return;
1279
+ }
1280
+
1281
+ const result = await this.liveVoiceSessionManager.startSession(frame, {
1282
+ sendFrame: async (serverFrame) => {
1283
+ this.sendLiveVoiceFrame(ws, serverFrame);
1284
+ },
1285
+ });
1286
+ if (result.status === "accepted") {
1287
+ ws.data.sessionId = result.sessionId;
1288
+ }
1289
+ return;
1290
+ }
1291
+
1292
+ const sessionId = ws.data.sessionId;
1293
+ if (!sessionId) {
1294
+ this.sendLiveVoiceStateError(
1295
+ ws,
1296
+ `Live voice ${frame.type} frame received before start`,
1297
+ );
1298
+ return;
1299
+ }
1300
+
1301
+ const handled = await this.liveVoiceSessionManager.handleClientFrame(
1302
+ sessionId,
1303
+ frame,
1304
+ );
1305
+ if (handled.status === "not_found") {
1306
+ ws.data.sessionId = undefined;
1307
+ this.sendLiveVoiceStateError(ws, "Live voice session is not active");
1308
+ return;
1309
+ }
1310
+
1311
+ if (frame.type === "end") {
1312
+ ws.data.sessionId = undefined;
1313
+ }
1314
+ }
1315
+
1316
+ private sendLiveVoiceStateError(
1317
+ ws: ServerWebSocket<LiveVoiceWebSocketData>,
1318
+ message: string,
1319
+ ): void {
1320
+ this.sendLiveVoiceError(ws, {
1321
+ code: LiveVoiceProtocolErrorCode.InvalidFrame,
1322
+ message,
1323
+ });
1324
+ }
1325
+
1326
+ private sendLiveVoiceError(
1327
+ ws: ServerWebSocket<LiveVoiceWebSocketData>,
1328
+ error: Pick<LiveVoiceProtocolError, "code" | "message">,
1329
+ ): void {
1330
+ this.sendLiveVoiceFrame(ws, {
1331
+ type: "error",
1332
+ seq: ws.data.lastSeq + 1,
1333
+ code: error.code,
1334
+ message: error.message,
1335
+ });
1336
+ }
1337
+
1338
+ private sendLiveVoiceFrame(
1339
+ ws: ServerWebSocket<LiveVoiceWebSocketData>,
1340
+ frame: LiveVoiceServerFrame,
1341
+ ): void {
1342
+ ws.data.lastSeq = Math.max(ws.data.lastSeq, frame.seq);
1343
+ ws.send(JSON.stringify(frame));
1344
+ }
1345
+
1346
+ private releaseLiveVoiceSession(
1347
+ data: LiveVoiceWebSocketData,
1348
+ reason: "websocket_close",
1349
+ ): void {
1350
+ const sessionId = data.sessionId;
1351
+ data.sessionId = undefined;
1352
+ if (!sessionId) return;
1353
+
1354
+ void this.liveVoiceSessionManager
1355
+ .releaseSession(sessionId, reason)
1356
+ .catch((err) => {
1357
+ log.warn(
1358
+ {
1359
+ error: err instanceof Error ? err.message : String(err),
1360
+ sessionId,
1361
+ },
1362
+ "Failed to release live voice session",
1363
+ );
1364
+ });
1365
+ }
1366
+
1434
1367
  private async handleTwilioWebhook(
1435
1368
  req: Request,
1436
1369
  path: string,
@@ -1470,762 +1403,4 @@ export class RuntimeHttpServer {
1470
1403
 
1471
1404
  return null;
1472
1405
  }
1473
-
1474
- private handleGetInterface(interfacePath: string): Response {
1475
- if (!this.interfacesDir) {
1476
- return httpError("NOT_FOUND", "Interface not found", 404);
1477
- }
1478
- const fullPath = resolve(this.interfacesDir, interfacePath);
1479
- if (
1480
- (fullPath !== this.interfacesDir &&
1481
- !fullPath.startsWith(this.interfacesDir + "/")) ||
1482
- !existsSync(fullPath)
1483
- ) {
1484
- return httpError("NOT_FOUND", "Interface not found", 404);
1485
- }
1486
- const source = readFileSync(fullPath, "utf-8");
1487
- return new Response(source, {
1488
- headers: { "Content-Type": "text/plain; charset=utf-8" },
1489
- });
1490
- }
1491
-
1492
- private buildAssistantAttention(attentionState: AttentionState | undefined):
1493
- | {
1494
- hasUnseenLatestAssistantMessage: boolean;
1495
- latestAssistantMessageAt?: number;
1496
- lastSeenAssistantMessageAt?: number;
1497
- lastSeenConfidence?: Confidence;
1498
- lastSeenSignalType?: SignalType;
1499
- }
1500
- | undefined {
1501
- if (!attentionState) return undefined;
1502
-
1503
- return {
1504
- hasUnseenLatestAssistantMessage:
1505
- attentionState.latestAssistantMessageAt != null &&
1506
- (attentionState.lastSeenAssistantMessageAt == null ||
1507
- attentionState.lastSeenAssistantMessageAt <
1508
- attentionState.latestAssistantMessageAt),
1509
- ...(attentionState.latestAssistantMessageAt != null
1510
- ? {
1511
- latestAssistantMessageAt: attentionState.latestAssistantMessageAt,
1512
- }
1513
- : {}),
1514
- ...(attentionState.lastSeenAssistantMessageAt != null
1515
- ? {
1516
- lastSeenAssistantMessageAt:
1517
- attentionState.lastSeenAssistantMessageAt,
1518
- }
1519
- : {}),
1520
- ...(attentionState.lastSeenConfidence != null
1521
- ? { lastSeenConfidence: attentionState.lastSeenConfidence }
1522
- : {}),
1523
- ...(attentionState.lastSeenSignalType != null
1524
- ? { lastSeenSignalType: attentionState.lastSeenSignalType }
1525
- : {}),
1526
- };
1527
- }
1528
-
1529
- private buildForkParent(
1530
- conversation: ConversationRow,
1531
- parentCache: Map<string, ConversationRow | null>,
1532
- ): { conversationId: string; messageId: string; title: string } | undefined {
1533
- const parentConversationId = conversation.forkParentConversationId;
1534
- const parentMessageId = conversation.forkParentMessageId;
1535
- if (!parentConversationId || !parentMessageId) return undefined;
1536
-
1537
- let parentConversation: ConversationRow | null | undefined =
1538
- parentCache.get(parentConversationId);
1539
- if (parentConversation === undefined) {
1540
- parentConversation = getConversation(parentConversationId);
1541
- parentCache.set(parentConversationId, parentConversation);
1542
- }
1543
- if (
1544
- !parentConversation ||
1545
- parentConversation.conversationType === "private"
1546
- ) {
1547
- return undefined;
1548
- }
1549
-
1550
- return {
1551
- conversationId: parentConversationId,
1552
- messageId: parentMessageId,
1553
- title: parentConversation.title ?? "Untitled",
1554
- };
1555
- }
1556
-
1557
- private serializeConversationSummary(params: {
1558
- conversation: ConversationRow;
1559
- binding?: ExternalConversationBinding | null;
1560
- attentionState?: AttentionState;
1561
- displayMeta?: {
1562
- displayOrder: number | null;
1563
- isPinned: boolean;
1564
- groupId: string | null;
1565
- };
1566
- parentCache: Map<string, ConversationRow | null>;
1567
- }) {
1568
- const { conversation, binding, attentionState, displayMeta, parentCache } =
1569
- params;
1570
- const originChannel = parseChannelId(conversation.originChannel);
1571
- const assistantAttention = this.buildAssistantAttention(attentionState);
1572
- const forkParent = this.buildForkParent(conversation, parentCache);
1573
-
1574
- return {
1575
- id: conversation.id,
1576
- title: conversation.title ?? "Untitled",
1577
- createdAt: conversation.createdAt,
1578
- updatedAt: conversation.updatedAt,
1579
- lastMessageAt: conversation.lastMessageAt,
1580
- conversationType: conversation.conversationType ?? "standard",
1581
- source: conversation.source ?? "user",
1582
- hostAccess: conversation.hostAccess === 1,
1583
- ...(conversation.scheduleJobId
1584
- ? { scheduleJobId: conversation.scheduleJobId }
1585
- : {}),
1586
- ...(binding
1587
- ? {
1588
- channelBinding: {
1589
- sourceChannel: binding.sourceChannel,
1590
- externalChatId: binding.externalChatId,
1591
- externalUserId: binding.externalUserId,
1592
- displayName: binding.displayName,
1593
- username: binding.username,
1594
- },
1595
- }
1596
- : {}),
1597
- ...(originChannel ? { conversationOriginChannel: originChannel } : {}),
1598
- ...(assistantAttention ? { assistantAttention } : {}),
1599
- ...(displayMeta?.isPinned
1600
- ? {
1601
- isPinned: true as const,
1602
- displayOrder: displayMeta.displayOrder,
1603
- }
1604
- : displayMeta?.displayOrder != null
1605
- ? {
1606
- displayOrder: displayMeta.displayOrder,
1607
- }
1608
- : {}),
1609
- groupId: displayMeta?.groupId ?? null,
1610
- ...(forkParent ? { forkParent } : {}),
1611
- ...(conversation.archivedAt != null
1612
- ? { archivedAt: conversation.archivedAt }
1613
- : {}),
1614
- };
1615
- }
1616
-
1617
- private buildConversationDetailResponse(conversationId: string) {
1618
- const conversation = getConversation(conversationId);
1619
- if (!conversation) {
1620
- return null;
1621
- }
1622
-
1623
- const bindings = externalConversationStore.getBindingsForConversations([
1624
- conversation.id,
1625
- ]);
1626
- const attentionStates = getAttentionStateByConversationIds([
1627
- conversation.id,
1628
- ]);
1629
- const displayMeta = getDisplayMetaForConversations([conversation.id]);
1630
- const parentCache = new Map<string, ConversationRow | null>();
1631
-
1632
- return {
1633
- conversation: this.serializeConversationSummary({
1634
- conversation,
1635
- binding: bindings.get(conversation.id),
1636
- attentionState: attentionStates.get(conversation.id),
1637
- displayMeta: displayMeta.get(conversation.id),
1638
- parentCache,
1639
- }),
1640
- };
1641
- }
1642
-
1643
- private getConversationManagementRouteDeps(): ConversationManagementDeps | null {
1644
- if (!this.conversationManagementDeps) {
1645
- return null;
1646
- }
1647
-
1648
- return {
1649
- ...this.conversationManagementDeps,
1650
- forkConversation:
1651
- this.conversationManagementDeps.forkConversation ??
1652
- (async ({ conversationId, throughMessageId }) => {
1653
- const forkedConversation = forkConversationInStore({
1654
- conversationId,
1655
- throughMessageId,
1656
- });
1657
- const detail = this.buildConversationDetailResponse(
1658
- forkedConversation.id,
1659
- );
1660
- if (!detail) {
1661
- throw new Error(
1662
- `Forked conversation ${forkedConversation.id} could not be loaded`,
1663
- );
1664
- }
1665
- return detail.conversation;
1666
- }),
1667
- };
1668
- }
1669
-
1670
- // ---------------------------------------------------------------------------
1671
- // Declarative route table
1672
- // ---------------------------------------------------------------------------
1673
-
1674
- /**
1675
- * Build the full set of route definitions. Routes are matched in order,
1676
- * so more specific patterns (e.g. `calls/:id/cancel`) must precede
1677
- * more general ones (e.g. `calls/:id`).
1678
- *
1679
- * Each domain's routes are defined in their own module under
1680
- * `./routes/` and composed here via spread. The composition order
1681
- * preserves the original top-to-bottom matching semantics.
1682
- */
1683
- private buildRouteTable(): RouteDefinition[] {
1684
- const assistantId = DAEMON_INTERNAL_ASSISTANT_ID;
1685
- const conversationManagementDeps =
1686
- this.getConversationManagementRouteDeps();
1687
-
1688
- return [
1689
- ...pairingRouteDefinitions({
1690
- getPairingContext: () => this.pairingContext,
1691
- }),
1692
- ...appRouteDefinitions(),
1693
- ...appManagementRouteDefinitions(),
1694
- ...secretRouteDefinitions({
1695
- getCesClient: this.getCesClient,
1696
- onProviderCredentialsChanged: this.onProviderCredentialsChanged,
1697
- }),
1698
- ...identityRouteDefinitions(),
1699
- ...upgradeBroadcastRouteDefinitions(),
1700
- ...workspaceCommitRouteDefinitions(),
1701
- ...migrationRollbackRouteDefinitions(),
1702
- ...debugRouteDefinitions(),
1703
- ...usageRouteDefinitions(),
1704
- ...telemetryRouteDefinitions(),
1705
- ...workspaceRouteDefinitions(),
1706
- ...memoryItemRouteDefinitions(),
1707
- ...conversationStarterRouteDefinitions(),
1708
- ...settingsRouteDefinitions(),
1709
- ...avatarRouteDefinitions(),
1710
- ...scheduleRouteDefinitions({
1711
- sendMessageDeps: this.sendMessageDeps,
1712
- }),
1713
- ...heartbeatRouteDefinitions({
1714
- getHeartbeatService: this.getHeartbeatService,
1715
- }),
1716
- ...filingRouteDefinitions({
1717
- getFilingService: this.getFilingService,
1718
- }),
1719
- ...homeStateRouteDefinitions(),
1720
- ...homeFeedRouteDefinitions(),
1721
- ...notificationRouteDefinitions(),
1722
- ...diagnosticsRouteDefinitions(),
1723
- ...logExportRouteDefinitions(),
1724
- ...profilerRouteDefinitions(),
1725
- ...documentRouteDefinitions(),
1726
- ...workItemRouteDefinitions(
1727
- this.sendMessageDeps
1728
- ? {
1729
- getOrCreateConversation: (conversationId) =>
1730
- this.sendMessageDeps!.getOrCreateConversation(conversationId),
1731
- findConversation: this.findConversation
1732
- ? (conversationId) => {
1733
- const s = this.findConversation!(conversationId);
1734
- if (!s || !("abort" in s)) return undefined;
1735
- return s as import("../daemon/conversation.js").Conversation;
1736
- }
1737
- : undefined,
1738
- }
1739
- : undefined,
1740
- ),
1741
- ...acpRouteDefinitions(),
1742
- ...subagentRouteDefinitions(),
1743
- ...conversationQueryRouteDefinitions({
1744
- getModelSetContext: this.getModelSetContext,
1745
- findConversationForQueue: this.findConversation
1746
- ? (id) => {
1747
- const s = this.findConversation!(id);
1748
- if (!s?.removeQueuedMessage) return undefined;
1749
- return { removeQueuedMessage: s.removeQueuedMessage.bind(s) };
1750
- }
1751
- : undefined,
1752
- }),
1753
- ...ttsRouteDefinitions(),
1754
- ...sttRouteDefinitions(),
1755
-
1756
- // Conversation list and seen signal — kept inline because they
1757
- // depend on multiple cross-cutting stores that aren't grouped
1758
- // into a single domain module.
1759
- {
1760
- endpoint: "conversations",
1761
- method: "GET",
1762
- handler: ({ url }) => {
1763
- const limit = Number(url.searchParams.get("limit") ?? 50);
1764
- const offset = Number(url.searchParams.get("offset") ?? 0);
1765
- const backgroundOnly =
1766
- url.searchParams.get("conversationType") === "background";
1767
- let rows = listConversations(limit, backgroundOnly, offset);
1768
- const totalCount = countConversations(backgroundOnly);
1769
- // On the first page, ensure all pinned conversations are included
1770
- // even if they fall outside the paginated window.
1771
- if (offset === 0 && !backgroundOnly) {
1772
- const pinned = listPinnedConversations();
1773
- const seen = new Set(rows.map((c) => c.id));
1774
- const missing = pinned.filter((c) => !seen.has(c.id));
1775
- if (missing.length > 0) {
1776
- rows = [...rows, ...missing];
1777
- }
1778
- }
1779
- const conversationIds = rows.map((c) => c.id);
1780
- const displayMeta = getDisplayMetaForConversations(conversationIds);
1781
- const bindings =
1782
- externalConversationStore.getBindingsForConversations(
1783
- conversationIds,
1784
- );
1785
- const attentionStates =
1786
- getAttentionStateByConversationIds(conversationIds);
1787
- const parentCache = new Map<string, ConversationRow | null>();
1788
- const nextOffset = offset + limit;
1789
- const response: Record<string, unknown> = {
1790
- conversations: rows.map((conversation) =>
1791
- this.serializeConversationSummary({
1792
- conversation,
1793
- binding: bindings.get(conversation.id),
1794
- attentionState: attentionStates.get(conversation.id),
1795
- displayMeta: displayMeta.get(conversation.id),
1796
- parentCache,
1797
- }),
1798
- ),
1799
- nextOffset,
1800
- hasMore: nextOffset < totalCount,
1801
- };
1802
- // Include groups array on first page only
1803
- if (offset === 0) {
1804
- const groups = listGroups();
1805
- response.groups = groups.map((g) => ({
1806
- id: g.id,
1807
- name: g.name,
1808
- sortPosition: g.sortPosition,
1809
- isSystemGroup: g.isSystemGroup,
1810
- }));
1811
- }
1812
- return Response.json(response);
1813
- },
1814
- },
1815
- ...conversationAttentionRouteDefinitions(),
1816
-
1817
- ...(conversationManagementDeps
1818
- ? conversationManagementRouteDefinitions(conversationManagementDeps)
1819
- : []),
1820
-
1821
- ...((): RouteDefinition[] => {
1822
- const sendMessageDeps = this.sendMessageDeps;
1823
- if (!sendMessageDeps) return [];
1824
- const analysisDeps = {
1825
- sendMessageDeps,
1826
- buildConversationDetailResponse: (id: string) =>
1827
- this.buildConversationDetailResponse(id),
1828
- };
1829
- // Also expose via the module singleton so background callers
1830
- // (e.g. job handlers) can invoke analyzeConversation() without
1831
- // HTTP-layer wiring. Daemon startup must never block, so failures
1832
- // to register the singleton are logged and swallowed.
1833
- try {
1834
- setAnalysisDeps(analysisDeps);
1835
- } catch (err) {
1836
- log.warn(
1837
- { err },
1838
- "Failed to register analysis deps singleton; background analysis jobs will be skipped",
1839
- );
1840
- }
1841
- return conversationAnalysisRouteDefinitions(analysisDeps);
1842
- })(),
1843
-
1844
- ...groupRouteDefinitions(),
1845
-
1846
- {
1847
- endpoint: "conversations/seen",
1848
- method: "POST",
1849
- handler: async ({ req }) => {
1850
- const body = (await req.json()) as Record<string, unknown>;
1851
- const rawConversationId = body.conversationId as string | undefined;
1852
- if (!rawConversationId)
1853
- return httpError("BAD_REQUEST", "Missing conversationId", 400);
1854
- // The client may send a conversation key rather than the internal
1855
- // conversation ID. Resolve to the internal ID to satisfy FK constraints.
1856
- const conversationId = resolveConversationId(rawConversationId);
1857
- if (!conversationId)
1858
- return httpError(
1859
- "NOT_FOUND",
1860
- `Unknown conversation: ${rawConversationId}`,
1861
- 404,
1862
- );
1863
- try {
1864
- // Snapshot current state to detect whether the seen cursor
1865
- // actually advances (avoids emitting on no-op signals).
1866
- // Only consider a conversation "unseen" when a latest assistant
1867
- // message exists and the seen cursor is behind it — matching
1868
- // the hasUnseenLatestAssistantMessage logic in buildAssistantAttention.
1869
- const priorState = getAttentionStateByConversationIds([
1870
- conversationId,
1871
- ]).get(conversationId);
1872
- const wasUnseen =
1873
- priorState != null &&
1874
- priorState.latestAssistantMessageAt != null &&
1875
- (priorState.lastSeenAssistantMessageAt == null ||
1876
- priorState.lastSeenAssistantMessageAt <
1877
- priorState.latestAssistantMessageAt);
1878
-
1879
- recordConversationSeenSignal({
1880
- conversationId,
1881
- sourceChannel: (body.sourceChannel as string) ?? "vellum",
1882
- signalType: ((body.signalType as string) ??
1883
- "macos_conversation_opened") as SignalType,
1884
- confidence: ((body.confidence as string) ??
1885
- "explicit") as Confidence,
1886
- source: (body.source as string) ?? "http-api",
1887
- evidenceText: body.evidenceText as string | undefined,
1888
- metadata: body.metadata as Record<string, unknown> | undefined,
1889
- observedAt: body.observedAt as number | undefined,
1890
- });
1891
- if (wasUnseen) {
1892
- assistantEventHub
1893
- .publish(
1894
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
1895
- type: "conversation_list_invalidated",
1896
- reason: "seen_changed",
1897
- }),
1898
- )
1899
- .catch((err) => {
1900
- log.warn(
1901
- { err },
1902
- "Failed to publish conversation_list_invalidated (seen_changed)",
1903
- );
1904
- });
1905
- }
1906
- return Response.json({ ok: true });
1907
- } catch (err) {
1908
- log.error(
1909
- { err, conversationId },
1910
- "POST /v1/conversations/seen: failed",
1911
- );
1912
- return httpError(
1913
- "INTERNAL_ERROR",
1914
- "Failed to record seen signal",
1915
- 500,
1916
- );
1917
- }
1918
- },
1919
- },
1920
-
1921
- {
1922
- endpoint: "conversations/unread",
1923
- method: "POST",
1924
- handler: async ({ req }) => {
1925
- const body = (await req.json()) as Record<string, unknown>;
1926
- const rawConversationId = body.conversationId as string | undefined;
1927
- if (!rawConversationId)
1928
- return httpError("BAD_REQUEST", "Missing conversationId", 400);
1929
- const conversationId = resolveConversationId(rawConversationId);
1930
- if (!conversationId)
1931
- return httpError(
1932
- "NOT_FOUND",
1933
- `Unknown conversation: ${rawConversationId}`,
1934
- 404,
1935
- );
1936
- try {
1937
- const changed = markConversationUnread(conversationId);
1938
- if (changed) {
1939
- assistantEventHub
1940
- .publish(
1941
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
1942
- type: "conversation_list_invalidated",
1943
- reason: "seen_changed",
1944
- }),
1945
- )
1946
- .catch((err) => {
1947
- log.warn(
1948
- { err },
1949
- "Failed to publish conversation_list_invalidated (seen_changed)",
1950
- );
1951
- });
1952
- }
1953
- return Response.json({ ok: true });
1954
- } catch (err) {
1955
- if (err instanceof UserError) {
1956
- return httpError("UNPROCESSABLE_ENTITY", err.message, 422);
1957
- }
1958
- log.error(
1959
- { err, conversationId },
1960
- "POST /v1/conversations/unread: failed",
1961
- );
1962
- return httpError(
1963
- "INTERNAL_ERROR",
1964
- "Failed to mark conversation unread",
1965
- 500,
1966
- );
1967
- }
1968
- },
1969
- },
1970
-
1971
- // conversations/:id must be registered AFTER all literal conversations/<word>
1972
- // routes above (attention, seen, unread) so the parameterized :id does not
1973
- // shadow them.
1974
- {
1975
- endpoint: "conversations/:id",
1976
- method: "GET",
1977
- handler: ({ params }) => {
1978
- const detail = this.buildConversationDetailResponse(params.id);
1979
- if (!detail) {
1980
- return httpError(
1981
- "NOT_FOUND",
1982
- `Conversation ${params.id} not found`,
1983
- 404,
1984
- );
1985
- }
1986
- return Response.json(detail);
1987
- },
1988
- },
1989
-
1990
- ...btwRouteDefinitions({
1991
- sendMessageDeps: this.sendMessageDeps,
1992
- }),
1993
-
1994
- ...conversationRouteDefinitions({
1995
- interfacesDir: this.interfacesDir,
1996
- sendMessageDeps: this.sendMessageDeps,
1997
- approvalConversationGenerator: this.approvalConversationGenerator,
1998
- suggestionCache: this.suggestionCache,
1999
- suggestionInFlight: this.suggestionInFlight,
2000
- getHeartbeatService: this.getHeartbeatService,
2001
- }),
2002
- ...playgroundRouteDefinitions({
2003
- getConversationById: async (id) => {
2004
- // Gate on DB existence first so genuinely-missing IDs return
2005
- // `undefined` (preserving the route handlers' 404 path) rather
2006
- // than triggering `getOrCreateConversation`'s create branch and
2007
- // masking the not-found case. For existing-but-not-loaded rows
2008
- // (e.g. freshly seeded by `POST /playground/seed-conversation`),
2009
- // hydrate the in-memory `Conversation` on demand so conv-scoped
2010
- // playground routes work without first opening the conversation
2011
- // in the main window.
2012
- if (!getConversation(id)) return undefined;
2013
- const sendDeps = this.sendMessageDeps;
2014
- if (!sendDeps) {
2015
- // Fall back to the in-memory active map when the daemon hasn't
2016
- // wired the hydration-capable accessor (e.g. unit tests).
2017
- const s = this.findConversation?.(id);
2018
- if (!s || !("abort" in s)) return undefined;
2019
- return s as import("../daemon/conversation.js").Conversation;
2020
- }
2021
- return sendDeps.getOrCreateConversation(id);
2022
- },
2023
- isPlaygroundEnabled: () =>
2024
- isAssistantFeatureFlagEnabled("compaction-playground", getConfig()),
2025
- listConversationsByTitlePrefix: (prefix) =>
2026
- listConversationsByTitlePrefix(prefix),
2027
- deleteConversationById: (id) => {
2028
- // Existence check first so we can report `false` for missing rows
2029
- // — `deleteConversation` always returns a result object even when
2030
- // no row matched.
2031
- if (!getConversation(id)) return false;
2032
- // Mirror the canonical DELETE /v1/conversations/:id handler in
2033
- // conversation-management-routes.ts: tear down the in-memory
2034
- // Conversation first (so a running agent loop can't write to a
2035
- // deleted row and trip FK constraints), then drop the DB row,
2036
- // then enqueue Qdrant vector cleanup for the returned segment
2037
- // and summary IDs. Without this, seeded-then-deleted playground
2038
- // conversations leak vectors and zombie Conversation objects.
2039
- if (this.findConversation?.(id)) {
2040
- this.conversationManagementDeps?.destroyConversation(id);
2041
- }
2042
- const deleted = deleteConversation(id);
2043
- for (const segId of deleted.segmentIds) {
2044
- enqueueMemoryJob("delete_qdrant_vectors", {
2045
- targetType: "segment",
2046
- targetId: segId,
2047
- });
2048
- }
2049
- for (const summaryId of deleted.deletedSummaryIds) {
2050
- enqueueMemoryJob("delete_qdrant_vectors", {
2051
- targetType: "summary",
2052
- targetId: summaryId,
2053
- });
2054
- }
2055
- return true;
2056
- },
2057
- createConversation: async (title) => {
2058
- const row = createConversation({ title });
2059
- return { id: row.id };
2060
- },
2061
- addMessage: async (conversationId, role, contentJson, options) => {
2062
- const persisted = await addMessage(
2063
- conversationId,
2064
- role,
2065
- contentJson,
2066
- undefined,
2067
- options,
2068
- );
2069
- return { id: persisted.id };
2070
- },
2071
- }),
2072
- ...globalSearchRouteDefinitions(),
2073
- ...approvalRouteDefinitions(),
2074
- ...hostBashRouteDefinitions(),
2075
- ...hostBrowserRouteDefinitions(),
2076
- ...hostCuRouteDefinitions(),
2077
- ...hostFileRouteDefinitions(),
2078
- ...(this.getSkillContext
2079
- ? skillRouteDefinitions({
2080
- getSkillContext: this.getSkillContext,
2081
- })
2082
- : []),
2083
- ...trustRulesRouteDefinitions(),
2084
- ...surfaceActionRouteDefinitions({
2085
- findConversation: this.findConversation,
2086
- findConversationBySurfaceId: this.findConversationBySurfaceId,
2087
- }),
2088
- ...surfaceContentRouteDefinitions({
2089
- findConversation: this.findConversation,
2090
- }),
2091
- ...guardianActionRouteDefinitions(),
2092
-
2093
- ...contactRouteDefinitions(),
2094
- ...inviteRouteDefinitions(),
2095
- // contacts/:id catch-all must follow invite routes to avoid shadowing
2096
- ...contactCatchAllRouteDefinitions(),
2097
-
2098
- ...telegramRouteDefinitions(),
2099
- ...channelVerificationRouteDefinitions(),
2100
- ...slackChannelRouteDefinitions(),
2101
- ...slackShareRouteDefinitions(),
2102
- ...twilioRouteDefinitions(),
2103
- ...vercelRouteDefinitions(),
2104
- ...channelReadinessRouteDefinitions(),
2105
- ...oauthProvidersRouteDefinitions(),
2106
- ...oauthAppsRouteDefinitions(),
2107
- ...attachmentRouteDefinitions(),
2108
-
2109
- ...(this.getRecordingDeps
2110
- ? recordingRouteDefinitions({
2111
- getRecordingDeps: this.getRecordingDeps,
2112
- })
2113
- : []),
2114
-
2115
- {
2116
- endpoint: "interfaces/:path*",
2117
- method: "GET",
2118
- policyKey: "interfaces",
2119
- handler: ({ params }) => this.handleGetInterface(params.path),
2120
- },
2121
-
2122
- ...channelRouteDefinitions({
2123
- assistantId,
2124
- processMessage: this.processMessage,
2125
- approvalCopyGenerator: this.approvalCopyGenerator,
2126
- approvalConversationGenerator: this.approvalConversationGenerator,
2127
- guardianActionCopyGenerator: this.guardianActionCopyGenerator,
2128
- guardianFollowUpConversationGenerator:
2129
- this.guardianFollowUpConversationGenerator,
2130
- getHeartbeatService: this.getHeartbeatService,
2131
- }),
2132
- ...callRouteDefinitions({ assistantId }),
2133
-
2134
- // Internal Twilio forwarding (gateway -> runtime) — kept inline
2135
- // because these reconstruct fake form-encoded requests from JSON,
2136
- // a pattern specific to the gateway-to-daemon bridge.
2137
- {
2138
- endpoint: "internal/twilio/voice-webhook",
2139
- method: "POST",
2140
- handler: async ({ req }) => {
2141
- const json = (await req.json()) as {
2142
- params: Record<string, string>;
2143
- originalUrl?: string;
2144
- };
2145
- const formBody = new URLSearchParams(json.params).toString();
2146
- const reconstructedUrl = json.originalUrl ?? req.url;
2147
- const fakeReq = new Request(reconstructedUrl, {
2148
- method: "POST",
2149
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
2150
- body: formBody,
2151
- });
2152
- return handleVoiceWebhook(fakeReq);
2153
- },
2154
- },
2155
- {
2156
- endpoint: "internal/twilio/status",
2157
- method: "POST",
2158
- handler: async ({ req }) => {
2159
- const json = (await req.json()) as {
2160
- params: Record<string, string>;
2161
- };
2162
- const formBody = new URLSearchParams(json.params).toString();
2163
- const fakeReq = new Request(req.url, {
2164
- method: "POST",
2165
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
2166
- body: formBody,
2167
- });
2168
- return handleStatusCallback(fakeReq);
2169
- },
2170
- },
2171
- {
2172
- endpoint: "internal/twilio/connect-action",
2173
- method: "POST",
2174
- handler: async ({ req }) => {
2175
- const json = (await req.json()) as {
2176
- params: Record<string, string>;
2177
- };
2178
- const formBody = new URLSearchParams(json.params).toString();
2179
- const fakeReq = new Request(req.url, {
2180
- method: "POST",
2181
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
2182
- body: formBody,
2183
- });
2184
- return handleConnectAction(fakeReq);
2185
- },
2186
- },
2187
-
2188
- ...brainGraphRouteDefinitions({ mintUiPageToken }),
2189
- ...eventsRouteDefinitions(),
2190
- ...traceEventRouteDefinitions(),
2191
- ...migrationRouteDefinitions(),
2192
- ...backupRouteDefinitions(),
2193
-
2194
- // User-defined routes under /x/* — must be LAST so built-in routes
2195
- // always take priority.
2196
- ...userRouteDefinitions(),
2197
-
2198
- // Internal OAuth callback (gateway -> runtime)
2199
- {
2200
- endpoint: "internal/oauth/callback",
2201
- method: "POST",
2202
- handler: async ({ req }) => {
2203
- const json = (await req.json()) as {
2204
- state: string;
2205
- code?: string;
2206
- error?: string;
2207
- };
2208
- if (!json.state)
2209
- return httpError("BAD_REQUEST", "Missing state parameter", 400);
2210
- if (json.error) {
2211
- const consumed = consumeCallbackError(json.state, json.error);
2212
- return consumed
2213
- ? Response.json({ ok: true })
2214
- : httpError("NOT_FOUND", "Unknown state", 404);
2215
- }
2216
- if (json.code) {
2217
- const consumed = consumeCallback(json.state, json.code);
2218
- return consumed
2219
- ? Response.json({ ok: true })
2220
- : httpError("NOT_FOUND", "Unknown state", 404);
2221
- }
2222
- return httpError(
2223
- "BAD_REQUEST",
2224
- "Missing code or error parameter",
2225
- 400,
2226
- );
2227
- },
2228
- },
2229
- ];
2230
- }
2231
1406
  }