@vellumai/assistant 0.6.5 → 0.7.0

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