@vellumai/assistant 0.6.6 → 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 (1346) hide show
  1. package/AGENTS.md +20 -0
  2. package/ARCHITECTURE.md +45 -36
  3. package/Dockerfile +26 -6
  4. package/README.md +8 -10
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +14 -20
  6. package/bun.lock +306 -119
  7. package/docs/architecture/memory.md +1 -90
  8. package/docs/architecture/security.md +15 -30
  9. package/docs/credential-execution-service.md +7 -5
  10. package/docs/skills.md +10 -10
  11. package/docs/stt-provider-onboarding.md +17 -45
  12. package/examples/plugins/echo/bun.lock +25 -0
  13. package/knip.json +8 -22
  14. package/node_modules/@vellumai/ces-client/bun.lock +33 -0
  15. package/node_modules/@vellumai/ces-client/package.json +25 -0
  16. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +631 -0
  17. package/node_modules/@vellumai/ces-client/src/__tests__/package-boundary.test.ts +138 -0
  18. package/node_modules/@vellumai/ces-client/src/credential-rpc.ts +13 -0
  19. package/node_modules/@vellumai/ces-client/src/http-credentials.ts +296 -0
  20. package/node_modules/@vellumai/ces-client/src/http-log-export.ts +111 -0
  21. package/node_modules/@vellumai/ces-client/src/index.ts +43 -0
  22. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +445 -0
  23. package/node_modules/@vellumai/credential-storage/src/__tests__/package-boundary.test.ts +32 -6
  24. package/node_modules/@vellumai/egress-proxy/src/__tests__/package-boundary.test.ts +32 -1
  25. package/node_modules/@vellumai/gateway-client/bun.lock +39 -0
  26. package/node_modules/@vellumai/gateway-client/package.json +23 -0
  27. package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +343 -0
  28. package/node_modules/@vellumai/gateway-client/src/__tests__/package-boundary.test.ts +140 -0
  29. package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +422 -0
  30. package/node_modules/@vellumai/gateway-client/src/index.ts +35 -0
  31. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +331 -0
  32. package/node_modules/@vellumai/gateway-client/src/types.ts +131 -0
  33. package/node_modules/@vellumai/gateway-client/tsconfig.json +20 -0
  34. package/node_modules/@vellumai/{ces-contracts → service-contracts}/bun.lock +1 -1
  35. package/node_modules/@vellumai/{ces-contracts → service-contracts}/package.json +4 -2
  36. package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts +5 -1
  37. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +155 -0
  38. package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +23 -0
  39. package/node_modules/@vellumai/service-contracts/src/index.ts +25 -0
  40. package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts} +6 -28
  41. package/node_modules/@vellumai/service-contracts/src/trust-rules.ts +116 -0
  42. package/node_modules/@vellumai/service-contracts/tsconfig.json +20 -0
  43. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +891 -0
  44. package/node_modules/@vellumai/skill-host-contracts/bun.lock +24 -0
  45. package/node_modules/@vellumai/skill-host-contracts/package.json +18 -0
  46. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +91 -0
  47. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +1348 -0
  48. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +6 -0
  49. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +11 -0
  50. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +32 -0
  51. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +333 -0
  52. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +444 -0
  53. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +20 -0
  54. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +12 -0
  55. package/openapi.yaml +2855 -556
  56. package/package.json +13 -7
  57. package/scripts/check-circular-deps.ts +80 -0
  58. package/scripts/generate-openapi.ts +24 -7
  59. package/{src/memory/graph/inspect.ts → scripts/memory-inspect.ts} +27 -27
  60. package/src/__tests__/access-request-decision.test.ts +2 -11
  61. package/src/__tests__/acp-session.test.ts +4 -150
  62. package/src/__tests__/actor-token-service.test.ts +17 -678
  63. package/src/__tests__/agent-loop-callsite-precedence.test.ts +2 -6
  64. package/src/__tests__/agent-loop-override-profile.test.ts +404 -0
  65. package/src/__tests__/agent-loop-thinking.test.ts +4 -4
  66. package/src/__tests__/agent-wake-override-profile.test.ts +261 -0
  67. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -1
  68. package/src/__tests__/anthropic-provider.test.ts +127 -15
  69. package/src/__tests__/app-routes-csp.test.ts +106 -55
  70. package/src/__tests__/approval-cascade.test.ts +3 -355
  71. package/src/__tests__/approval-conversation-turn.test.ts +3 -8
  72. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
  73. package/src/__tests__/approval-primitive.test.ts +2 -1
  74. package/src/__tests__/approval-routes-http.test.ts +34 -451
  75. package/src/__tests__/assistant-events-sse-hardening.test.ts +73 -80
  76. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -3
  77. package/src/__tests__/attachment-upload-trusted-source.test.ts +139 -0
  78. package/src/__tests__/attachments-store.test.ts +46 -1
  79. package/src/__tests__/audit-log-rotation.test.ts +2 -1
  80. package/src/__tests__/auto-analysis-end-to-end.test.ts +8 -20
  81. package/src/__tests__/background-shell-bash.test.ts +227 -0
  82. package/src/__tests__/background-shell-host-bash.test.ts +474 -0
  83. package/src/__tests__/background-tool-registry.test.ts +145 -0
  84. package/src/__tests__/background-tool-routes.test.ts +175 -0
  85. package/src/__tests__/btw-routes.test.ts +147 -183
  86. package/src/__tests__/call-controller.test.ts +15 -2
  87. package/src/__tests__/call-conversation-messages.test.ts +2 -1
  88. package/src/__tests__/call-domain.test.ts +2 -2
  89. package/src/__tests__/call-pointer-messages.test.ts +11 -13
  90. package/src/__tests__/call-recovery.test.ts +2 -1
  91. package/src/__tests__/call-routes-http.test.ts +3 -14
  92. package/src/__tests__/call-store.test.ts +2 -1
  93. package/src/__tests__/cancel-resolves-conversation-key.test.ts +31 -62
  94. package/src/__tests__/canonical-guardian-store.test.ts +2 -2
  95. package/src/__tests__/catalog-files.test.ts +0 -26
  96. package/src/__tests__/ces-rpc-credential-backend.test.ts +1 -1
  97. package/src/__tests__/channel-approval-routes.test.ts +79 -49
  98. package/src/__tests__/channel-approval.test.ts +9 -7
  99. package/src/__tests__/channel-approvals.test.ts +9 -180
  100. package/src/__tests__/channel-delivery-store.test.ts +11 -10
  101. package/src/__tests__/channel-guardian.test.ts +14 -25
  102. package/src/__tests__/channel-readiness-service.test.ts +8 -6
  103. package/src/__tests__/channel-reply-delivery.test.ts +3 -19
  104. package/src/__tests__/channel-retry-sweep.test.ts +2 -5
  105. package/src/__tests__/checker.test.ts +274 -3921
  106. package/src/__tests__/circuit-breaker-pipeline.test.ts +1 -1
  107. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +208 -0
  108. package/src/__tests__/cli.test.ts +1 -38
  109. package/src/__tests__/compaction-events.test.ts +0 -1
  110. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  111. package/src/__tests__/compaction-strip-metadata-clear.test.ts +2 -2
  112. package/src/__tests__/compaction-timeout-recovery.test.ts +1 -1
  113. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -7
  114. package/src/__tests__/config-model-image-provider.test.ts +0 -1
  115. package/src/__tests__/config-schema-cmd.test.ts +1 -1
  116. package/src/__tests__/config-schema.test.ts +30 -221
  117. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -25
  118. package/src/__tests__/contact-store-user-file.test.ts +2 -1
  119. package/src/__tests__/contacts-tools.test.ts +56 -29
  120. package/src/__tests__/contacts-write.test.ts +6 -61
  121. package/src/__tests__/context-search-agent-protocol.test.ts +230 -0
  122. package/src/__tests__/context-search-agent-runner.test.ts +998 -0
  123. package/src/__tests__/context-search-conversations-source.test.ts +320 -0
  124. package/src/__tests__/context-search-fanout.test.ts +380 -0
  125. package/src/__tests__/context-search-memory-source.test.ts +311 -0
  126. package/src/__tests__/context-search-pkb-source.test.ts +444 -0
  127. package/src/__tests__/context-search-types.test.ts +95 -0
  128. package/src/__tests__/context-search-workspace-source.test.ts +545 -0
  129. package/src/__tests__/context-window-manager.test.ts +25 -0
  130. package/src/__tests__/conversation-abort-tool-results.test.ts +10 -1
  131. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +631 -0
  132. package/src/__tests__/conversation-agent-loop-overflow.test.ts +15 -2
  133. package/src/__tests__/conversation-agent-loop.test.ts +24 -2
  134. package/src/__tests__/conversation-analysis-routes.test.ts +60 -82
  135. package/src/__tests__/conversation-attachments.test.ts +9 -20
  136. package/src/__tests__/conversation-attention-store.test.ts +2 -1
  137. package/src/__tests__/conversation-attention-telegram.test.ts +4 -2
  138. package/src/__tests__/conversation-clear-safety.test.ts +53 -95
  139. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -39
  140. package/src/__tests__/conversation-crud-inference-profile.test.ts +54 -0
  141. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +63 -157
  142. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  143. package/src/__tests__/conversation-disk-view.test.ts +5 -4
  144. package/src/__tests__/conversation-fork-crud.test.ts +26 -55
  145. package/src/__tests__/conversation-fork-route.test.ts +5 -74
  146. package/src/__tests__/conversation-inference-profile-list.test.ts +128 -0
  147. package/src/__tests__/conversation-inference-profile-route.test.ts +216 -0
  148. package/src/__tests__/conversation-init.benchmark.test.ts +4 -81
  149. package/src/__tests__/conversation-key-store-disk-view.test.ts +2 -1
  150. package/src/__tests__/conversation-lifecycle.test.ts +0 -1
  151. package/src/__tests__/conversation-list-source.test.ts +2 -2
  152. package/src/__tests__/conversation-load-history-repair.test.ts +0 -1
  153. package/src/__tests__/conversation-pairing.test.ts +0 -1
  154. package/src/__tests__/conversation-pre-run-repair.test.ts +137 -297
  155. package/src/__tests__/conversation-process-callsite.test.ts +0 -1
  156. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -1
  157. package/src/__tests__/conversation-queue.test.ts +1 -33
  158. package/src/__tests__/conversation-routes-disk-view.test.ts +124 -97
  159. package/src/__tests__/conversation-routes-guardian-reply.test.ts +80 -55
  160. package/src/__tests__/conversation-routes-slash-commands.test.ts +83 -12
  161. package/src/__tests__/conversation-runtime-assembly.test.ts +41 -84
  162. package/src/__tests__/conversation-slash-commands.test.ts +6 -43
  163. package/src/__tests__/conversation-slash-queue.test.ts +0 -1
  164. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  165. package/src/__tests__/conversation-speed-override.test.ts +0 -1
  166. package/src/__tests__/conversation-starter-routes.test.ts +177 -55
  167. package/src/__tests__/conversation-starters-cadence.test.ts +2 -2
  168. package/src/__tests__/conversation-store.test.ts +2 -375
  169. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
  170. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +6 -6
  171. package/src/__tests__/conversation-unread-route.test.ts +1 -1
  172. package/src/__tests__/conversation-usage.test.ts +2 -1
  173. package/src/__tests__/conversation-wipe.test.ts +2 -103
  174. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -1
  175. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  176. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  177. package/src/__tests__/conversations-defer-cli.test.ts +150 -0
  178. package/src/__tests__/credential-execution-admin-cli.test.ts +1 -1
  179. package/src/__tests__/credential-execution-api-key-propagation.test.ts +2 -2
  180. package/src/__tests__/credential-execution-approval-bridge.test.ts +22 -289
  181. package/src/__tests__/credential-execution-client.test.ts +1 -1
  182. package/src/__tests__/credential-execution-managed-contract.test.ts +1 -1
  183. package/src/__tests__/credential-security-invariants.test.ts +14 -0
  184. package/src/__tests__/credentials-cli.test.ts +45 -21
  185. package/src/__tests__/daemon-credential-client.test.ts +23 -108
  186. package/src/__tests__/db-acp-history.test.ts +284 -0
  187. package/src/__tests__/db-activation-state.test.ts +240 -0
  188. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +2 -1
  189. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +248 -0
  190. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +2 -1
  191. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +116 -0
  192. package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +132 -0
  193. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  194. package/src/__tests__/delete-propagation.test.ts +3 -2
  195. package/src/__tests__/deterministic-verification-control-plane.test.ts +39 -32
  196. package/src/__tests__/dm-backfill.test.ts +3 -2
  197. package/src/__tests__/edit-propagation.test.ts +5 -7
  198. package/src/__tests__/embedding-managed-proxy-selection.test.ts +1 -1
  199. package/src/__tests__/empty-response-pipeline.test.ts +1 -1
  200. package/src/__tests__/events-client-registration.test.ts +297 -0
  201. package/src/__tests__/file-write-tool.test.ts +2 -4
  202. package/src/__tests__/filing-service.test.ts +144 -17
  203. package/src/__tests__/followup-tools.test.ts +2 -1
  204. package/src/__tests__/gateway-client-managed-outbound.test.ts +8 -12
  205. package/src/__tests__/gateway-only-enforcement.test.ts +2 -6
  206. package/src/__tests__/gateway-only-guard.test.ts +4 -3
  207. package/src/__tests__/gemini-provider.test.ts +276 -10
  208. package/src/__tests__/graph-extraction-event-date.test.ts +30 -0
  209. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -1
  210. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -2
  211. package/src/__tests__/guardian-action-followup-store.test.ts +2 -1
  212. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +9 -9
  213. package/src/__tests__/guardian-action-late-reply.test.ts +2 -1
  214. package/src/__tests__/guardian-action-store.test.ts +2 -1
  215. package/src/__tests__/guardian-action-sweep.test.ts +9 -8
  216. package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -1
  217. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +21 -118
  218. package/src/__tests__/guardian-dispatch.test.ts +14 -11
  219. package/src/__tests__/guardian-grant-minting.test.ts +9 -15
  220. package/src/__tests__/guardian-outbound-http.test.ts +71 -106
  221. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -2
  222. package/src/__tests__/guardian-routing-invariants.test.ts +34 -90
  223. package/src/__tests__/guardian-routing-state.test.ts +14 -22
  224. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -2
  225. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +253 -0
  226. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +8 -4
  227. package/src/__tests__/heartbeat-service.test.ts +39 -21
  228. package/src/__tests__/helpers/call-route-handler.ts +72 -0
  229. package/src/__tests__/helpers/channel-test-adapter.ts +161 -0
  230. package/src/__tests__/helpers/gateway-classify-mock.ts +67 -0
  231. package/src/__tests__/helpers/mock-logger.ts +36 -0
  232. package/src/__tests__/history-repair-pipeline.test.ts +1 -1
  233. package/src/__tests__/home-state-routes.test.ts +10 -31
  234. package/src/__tests__/host-browser-e2e-cloud.test.ts +2 -1
  235. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +12 -2
  236. package/src/__tests__/host-browser-routes.test.ts +36 -91
  237. package/src/__tests__/host-browser-ws-events-e2e.test.ts +10 -2
  238. package/src/__tests__/host-proxy-interface.test.ts +3 -3
  239. package/src/__tests__/host-shell-tool.test.ts +2 -4
  240. package/src/__tests__/host-transfer-pending-interactions.test.ts +160 -0
  241. package/src/__tests__/host-transfer-proxy.test.ts +733 -0
  242. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  243. package/src/__tests__/http-user-message-parity.test.ts +20 -11
  244. package/src/__tests__/inbound-invite-redemption.test.ts +3 -2
  245. package/src/__tests__/injector-chain.test.ts +16 -17
  246. package/src/__tests__/inline-skill-load-permissions.test.ts +41 -206
  247. package/src/__tests__/install-skill-routing.test.ts +1 -1
  248. package/src/__tests__/invite-redemption-service.test.ts +2 -1
  249. package/src/__tests__/invite-routes-http.test.ts +80 -12
  250. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -1
  251. package/src/__tests__/jobs-store-upsert-debounced.test.ts +2 -1
  252. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +157 -0
  253. package/src/__tests__/list-messages-attachments.test.ts +52 -55
  254. package/src/__tests__/list-messages-page-latest.test.ts +283 -0
  255. package/src/__tests__/list-messages-tool-merge.test.ts +16 -17
  256. package/src/__tests__/llm-call-pipeline.test.ts +7 -8
  257. package/src/__tests__/llm-context-normalization.test.ts +69 -4
  258. package/src/__tests__/llm-context-route-provider.test.ts +39 -113
  259. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -1
  260. package/src/__tests__/llm-resolver.test.ts +211 -0
  261. package/src/__tests__/llm-schema.test.ts +57 -1
  262. package/src/__tests__/llm-usage-store.test.ts +2 -1
  263. package/src/__tests__/log-export-workspace.test.ts +28 -17
  264. package/src/__tests__/mcp-abort-signal.test.ts +2 -3
  265. package/src/__tests__/mcp-client-auth.test.ts +2 -3
  266. package/src/__tests__/memory-admin-recall.test.ts +221 -0
  267. package/src/__tests__/memory-recall-log-store.test.ts +2 -1
  268. package/src/__tests__/memory-retrieval-pipeline.test.ts +6 -8
  269. package/src/__tests__/memory-upsert-concurrency.test.ts +2 -1
  270. package/src/__tests__/migration-cross-version-compatibility.test.ts +14 -13
  271. package/src/__tests__/migration-export-http.test.ts +17 -17
  272. package/src/__tests__/migration-export-to-gcs.test.ts +491 -0
  273. package/src/__tests__/migration-import-commit-http.test.ts +16 -16
  274. package/src/__tests__/migration-import-from-gcs.test.ts +533 -0
  275. package/src/__tests__/migration-import-from-url.test.ts +16 -23
  276. package/src/__tests__/migration-import-preflight-http.test.ts +13 -13
  277. package/src/__tests__/migration-jobs-status.test.ts +164 -0
  278. package/src/__tests__/migration-validate-http.test.ts +48 -83
  279. package/src/__tests__/mock-gateway-ipc.ts +32 -62
  280. package/src/__tests__/model-intents.test.ts +15 -2
  281. package/src/__tests__/nl-approval-parser.test.ts +13 -17
  282. package/src/__tests__/non-member-access-request.test.ts +13 -5
  283. package/src/__tests__/notification-guardian-path.test.ts +15 -8
  284. package/src/__tests__/notification-schedule-notify-dedup.test.ts +2 -1
  285. package/src/__tests__/notification-telegram-adapter.test.ts +57 -55
  286. package/src/__tests__/oauth-apps-routes.test.ts +76 -122
  287. package/src/__tests__/oauth-cli.test.ts +14 -1
  288. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  289. package/src/__tests__/oauth-provider-visibility.test.ts +3 -1
  290. package/src/__tests__/oauth-providers-routes.test.ts +78 -101
  291. package/src/__tests__/oauth-store.test.ts +3 -1
  292. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -3
  293. package/src/__tests__/openai-provider.test.ts +105 -6
  294. package/src/__tests__/openai-responses-provider.test.ts +146 -4
  295. package/src/__tests__/openrouter-provider-only.test.ts +22 -4
  296. package/src/__tests__/overflow-reduce-pipeline.test.ts +4 -9
  297. package/src/__tests__/permission-types.test.ts +3 -18
  298. package/src/__tests__/persistence-pipeline.test.ts +3 -2
  299. package/src/__tests__/pipeline-runner.test.ts +1 -1
  300. package/src/__tests__/platform-bash-auto-approve.test.ts +27 -20
  301. package/src/__tests__/platform.test.ts +11 -63
  302. package/src/__tests__/playbook-execution.test.ts +2 -1
  303. package/src/__tests__/playbook-tools.test.ts +2 -1
  304. package/src/__tests__/plugin-bootstrap.test.ts +51 -5
  305. package/src/__tests__/plugin-registry.test.ts +30 -0
  306. package/src/__tests__/plugin-route-contribution.test.ts +17 -11
  307. package/src/__tests__/plugin-skill-contribution.test.ts +3 -3
  308. package/src/__tests__/plugin-tool-contribution.test.ts +10 -4
  309. package/src/__tests__/plugin-types.test.ts +1 -1
  310. package/src/__tests__/pricing.test.ts +151 -2
  311. package/src/__tests__/profiler-routes.test.ts +112 -177
  312. package/src/__tests__/provider-send-message-override-profile.test.ts +223 -0
  313. package/src/__tests__/proxy-approval-callback.test.ts +6 -554
  314. package/src/__tests__/qdrant-collection-migration.test.ts +7 -7
  315. package/src/__tests__/reaction-persistence.test.ts +3 -2
  316. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  317. package/src/__tests__/recording-handler.test.ts +0 -2
  318. package/src/__tests__/registry.test.ts +1 -0
  319. package/src/__tests__/relay-server.test.ts +19 -4
  320. package/src/__tests__/require-fresh-approval.test.ts +19 -168
  321. package/src/__tests__/resolve-trust-class.test.ts +2 -1
  322. package/src/__tests__/retry-thinking-tool-choice.test.ts +19 -7
  323. package/src/__tests__/retry-verbosity-normalization.test.ts +139 -0
  324. package/src/__tests__/runtime-attachment-metadata.test.ts +26 -6
  325. package/src/__tests__/runtime-events-sse-parity.test.ts +12 -13
  326. package/src/__tests__/runtime-events-sse.test.ts +13 -21
  327. package/src/__tests__/schedule-routes.test.ts +226 -129
  328. package/src/__tests__/schedule-store.test.ts +119 -1
  329. package/src/__tests__/schedule-tools.test.ts +2 -1
  330. package/src/__tests__/scheduler-recurrence.test.ts +2 -1
  331. package/src/__tests__/scheduler-reuse-conversation.test.ts +2 -1
  332. package/src/__tests__/scheduler-wake.test.ts +356 -0
  333. package/src/__tests__/scoped-approval-grants.test.ts +2 -1
  334. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -1
  335. package/src/__tests__/secret-detection-handler.test.ts +2 -9
  336. package/src/__tests__/secret-ingress-http.test.ts +38 -21
  337. package/src/__tests__/secret-routes-managed-proxy.test.ts +46 -102
  338. package/src/__tests__/secret-scanner-executor.test.ts +1 -2
  339. package/src/__tests__/send-endpoint-busy.test.ts +38 -25
  340. package/src/__tests__/sequence-store.test.ts +2 -1
  341. package/src/__tests__/server-history-render.test.ts +2 -2
  342. package/src/__tests__/service-contracts-import-guard.test.ts +185 -0
  343. package/src/__tests__/set-permission-mode.test.ts +0 -10
  344. package/src/__tests__/settings-routes.test.ts +35 -68
  345. package/src/__tests__/skill-boundary-guard.test.ts +105 -0
  346. package/src/__tests__/skill-load-inline-command.test.ts +2 -2
  347. package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
  348. package/src/__tests__/skill-runtime-path.test.ts +64 -0
  349. package/src/__tests__/skills-file-content-endpoint.test.ts +0 -2
  350. package/src/__tests__/slack-inbound-verification.test.ts +11 -2
  351. package/src/__tests__/slack-messaging-token-resolution.test.ts +1 -3
  352. package/src/__tests__/slack-reaction-approvals.test.ts +4 -4
  353. package/src/__tests__/slack-share-routes.test.ts +37 -72
  354. package/src/__tests__/subagent-call-site-routing.test.ts +79 -0
  355. package/src/__tests__/subagent-fork-spawn.test.ts +20 -28
  356. package/src/__tests__/subagent-notify-parent.test.ts +6 -29
  357. package/src/__tests__/subagent-role-registry.test.ts +3 -3
  358. package/src/__tests__/subagent-spawn-tool-fork.test.ts +52 -104
  359. package/src/__tests__/subagent-tools.test.ts +0 -1
  360. package/src/__tests__/suggestion-routes.test.ts +55 -62
  361. package/src/__tests__/task-compiler.test.ts +2 -1
  362. package/src/__tests__/task-management-tools.test.ts +2 -1
  363. package/src/__tests__/task-memory-cleanup.test.ts +2 -1
  364. package/src/__tests__/task-scheduler.test.ts +2 -1
  365. package/src/__tests__/telegram-config.test.ts +0 -1
  366. package/src/__tests__/terminal-tools.test.ts +5 -314
  367. package/src/__tests__/test-preload.ts +0 -11
  368. package/src/__tests__/thread-backfill.test.ts +3 -2
  369. package/src/__tests__/token-estimate-pipeline.test.ts +68 -15
  370. package/src/__tests__/tool-approval-handler.test.ts +21 -63
  371. package/src/__tests__/tool-audit-listener.test.ts +3 -3
  372. package/src/__tests__/tool-domain-event-publisher.test.ts +3 -3
  373. package/src/__tests__/tool-error-pipeline.test.ts +6 -6
  374. package/src/__tests__/tool-execute-pipeline.test.ts +6 -8
  375. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +64 -1
  376. package/src/__tests__/tool-executor-lifecycle-events.test.ts +28 -56
  377. package/src/__tests__/tool-executor.test.ts +322 -1633
  378. package/src/__tests__/tool-grant-request-escalation.test.ts +90 -311
  379. package/src/__tests__/tool-result-truncate-pipeline.test.ts +1 -1
  380. package/src/__tests__/trust-context-guards.test.ts +1 -1
  381. package/src/__tests__/trusted-contact-approval-notifier.test.ts +7 -15
  382. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +178 -354
  383. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +3 -2
  384. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -2
  385. package/src/__tests__/trusted-contact-verification.test.ts +2 -1
  386. package/src/__tests__/turn-boundary-resolution.test.ts +2 -1
  387. package/src/__tests__/twilio-routes.test.ts +25 -66
  388. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -7
  389. package/src/__tests__/usage-routes.test.ts +73 -90
  390. package/src/__tests__/user-plugin-loader.test.ts +54 -12
  391. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -2
  392. package/src/__tests__/verification-control-plane-policy.test.ts +95 -14
  393. package/src/__tests__/voice-ingress-preflight.test.ts +5 -5
  394. package/src/__tests__/voice-invite-redemption.test.ts +2 -1
  395. package/src/__tests__/voice-scoped-grant-consumer.test.ts +3 -3
  396. package/src/__tests__/voice-session-bridge.test.ts +285 -106
  397. package/src/__tests__/volume-security-guard.test.ts +0 -2
  398. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -1
  399. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +3 -1
  400. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +2 -1
  401. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +1 -1
  402. package/src/__tests__/workspace-migration-052-seed-default-inference-profiles.test.ts +260 -0
  403. package/src/__tests__/workspace-migration-053-release-notes-acp-codex.test.ts +225 -0
  404. package/src/__tests__/workspace-migration-054-seed-recall-callsite.test.ts +235 -0
  405. package/src/__tests__/workspace-migration-055-release-notes-agentic-recall.test.ts +128 -0
  406. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +232 -0
  407. package/src/__tests__/workspace-migration-acp-sessions-ui.test.ts +144 -0
  408. package/src/__tests__/workspace-migration-drop-user-md.test.ts +1 -1
  409. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +274 -0
  410. package/src/acp/__tests__/client-handler.test.ts +64 -0
  411. package/src/acp/__tests__/helpers/acp-config-stub.ts +62 -0
  412. package/src/acp/__tests__/helpers/which-stub.ts +45 -0
  413. package/src/acp/__tests__/session-manager-persistence.test.ts +366 -0
  414. package/src/acp/__tests__/session-manager-startup.test.ts +159 -0
  415. package/src/acp/__tests__/session-manager.test.ts +83 -0
  416. package/src/acp/client-handler.ts +23 -139
  417. package/src/acp/resolve-agent.test.ts +291 -0
  418. package/src/acp/resolve-agent.ts +176 -0
  419. package/src/acp/session-manager.ts +166 -7
  420. package/src/acp/types.ts +2 -50
  421. package/src/agent/loop.ts +37 -14
  422. package/src/agent/message-types.ts +0 -2
  423. package/src/approvals/AGENTS.md +1 -1
  424. package/src/approvals/__tests__/guardian-feed-event.test.ts +1 -9
  425. package/src/approvals/approval-primitive.ts +3 -20
  426. package/src/approvals/guardian-decision-primitive.ts +37 -68
  427. package/src/approvals/guardian-request-resolvers.ts +29 -103
  428. package/src/avatar/character-components.ts +6 -6
  429. package/src/{config/bundled-skills/settings/tools → avatar}/identity-avatar.ts +1 -1
  430. package/src/backup/__tests__/backup-worker.test.ts +0 -2
  431. package/src/backup/__tests__/paths.test.ts +3 -2
  432. package/src/backup/backup-worker.ts +1 -10
  433. package/src/backup/paths.ts +2 -18
  434. package/src/backup/restore.ts +7 -11
  435. package/src/browser/__tests__/operations.test.ts +0 -35
  436. package/src/browser/operations.ts +1 -47
  437. package/src/bundler/package-resolver.ts +2 -6
  438. package/src/calls/active-call-lease.ts +1 -1
  439. package/src/calls/call-constants.ts +1 -1
  440. package/src/calls/call-controller.ts +1 -5
  441. package/src/calls/call-domain.ts +14 -14
  442. package/src/calls/call-pointer-messages.ts +4 -9
  443. package/src/calls/call-store.ts +2 -1
  444. package/src/calls/guardian-action-sweep.ts +9 -25
  445. package/src/calls/guardian-dispatch.ts +1 -20
  446. package/src/calls/media-stream-audio-transcode.ts +2 -41
  447. package/src/calls/media-stream-server.ts +2 -3
  448. package/src/calls/media-stream-stt-session.ts +1 -3
  449. package/src/calls/relay-access-wait.ts +5 -8
  450. package/src/calls/relay-server.ts +15 -18
  451. package/src/calls/relay-setup-router.ts +2 -2
  452. package/src/calls/relay-verification.ts +4 -4
  453. package/src/calls/twilio-rest.ts +1 -1
  454. package/src/calls/twilio-routes.ts +160 -78
  455. package/src/calls/voice-control-protocol.ts +10 -10
  456. package/src/calls/voice-ingress-preflight.ts +2 -2
  457. package/src/calls/voice-session-bridge.ts +137 -42
  458. package/src/channels/__tests__/types.test.ts +25 -3
  459. package/src/channels/permission-profiles.ts +2 -72
  460. package/src/channels/types.ts +42 -26
  461. package/src/cli/AGENTS.md +1 -0
  462. package/src/cli/__tests__/notifications.test.ts +12 -10
  463. package/src/cli/commands/__tests__/attachment.test.ts +14 -8
  464. package/src/cli/commands/__tests__/backup.test.ts +3 -14
  465. package/src/cli/commands/__tests__/browser.test.ts +36 -31
  466. package/src/cli/commands/__tests__/cache.test.ts +23 -18
  467. package/src/cli/commands/__tests__/memory-v2.test.ts +396 -0
  468. package/src/cli/commands/__tests__/task.test.ts +36 -35
  469. package/src/cli/commands/__tests__/trust.test.ts +602 -0
  470. package/src/cli/commands/__tests__/ui-confirm.test.ts +14 -14
  471. package/src/cli/commands/__tests__/ui.test.ts +17 -17
  472. package/src/cli/commands/__tests__/watchers.test.ts +29 -29
  473. package/src/cli/commands/__tests__/webhooks.test.ts +544 -0
  474. package/src/cli/commands/attachment.ts +12 -8
  475. package/src/cli/commands/auth.ts +1 -1
  476. package/src/cli/commands/avatar.ts +192 -9
  477. package/src/cli/commands/backup.ts +14 -44
  478. package/src/cli/commands/browser.ts +52 -4
  479. package/src/cli/commands/cache.ts +7 -5
  480. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  481. package/src/cli/commands/clients.ts +11 -12
  482. package/src/cli/commands/completions.ts +1 -1
  483. package/src/cli/commands/contacts.ts +10 -10
  484. package/src/cli/commands/conversations-defer.ts +364 -0
  485. package/src/cli/commands/conversations-import.ts +2 -3
  486. package/src/cli/commands/conversations.ts +63 -53
  487. package/src/cli/commands/credential-execution.ts +1 -1
  488. package/src/cli/commands/credentials.ts +139 -5
  489. package/src/cli/commands/default-action.ts +1 -1
  490. package/src/cli/commands/domain.ts +2 -2
  491. package/src/cli/commands/email.ts +7 -7
  492. package/src/cli/commands/image-generation.ts +1 -1
  493. package/src/cli/commands/keys.ts +2 -2
  494. package/src/cli/commands/mcp.ts +1 -1
  495. package/src/cli/commands/memory-v2.ts +343 -0
  496. package/src/cli/commands/memory.ts +8 -8
  497. package/src/cli/commands/notifications.ts +21 -20
  498. package/src/cli/commands/oauth/__tests__/connect.test.ts +23 -5
  499. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +1 -1
  500. package/src/cli/commands/oauth/__tests__/mode.test.ts +1 -1
  501. package/src/cli/commands/oauth/__tests__/status.test.ts +1 -1
  502. package/src/cli/commands/oauth/__tests__/token.test.ts +1 -1
  503. package/src/cli/commands/oauth/connect.ts +2 -2
  504. package/src/cli/commands/oauth/shared.ts +29 -2
  505. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -6
  506. package/src/cli/commands/platform/__tests__/connect.test.ts +23 -11
  507. package/src/cli/commands/platform/__tests__/disconnect.test.ts +22 -10
  508. package/src/cli/commands/platform/__tests__/status.test.ts +22 -10
  509. package/src/cli/commands/platform/connect.ts +3 -3
  510. package/src/cli/commands/platform/disconnect.ts +4 -6
  511. package/src/cli/commands/platform/index.ts +12 -10
  512. package/src/cli/commands/routes.ts +7 -1
  513. package/src/cli/commands/sequence.ts +7 -7
  514. package/src/cli/commands/skills.ts +188 -82
  515. package/src/cli/commands/task.ts +12 -10
  516. package/src/cli/commands/trust.ts +460 -162
  517. package/src/cli/commands/ui.ts +3 -3
  518. package/src/cli/commands/usage.ts +10 -5
  519. package/src/cli/commands/watchers.ts +8 -8
  520. package/src/cli/commands/webhooks.ts +270 -0
  521. package/src/cli/lib/daemon-avatar-client.ts +37 -0
  522. package/src/cli/lib/daemon-credential-client.ts +27 -189
  523. package/src/cli/lib/ipc-params.ts +22 -0
  524. package/src/cli/program.ts +4 -0
  525. package/src/cli.ts +1 -61
  526. package/src/config/acp-defaults.test.ts +57 -0
  527. package/src/config/acp-defaults.ts +40 -0
  528. package/src/config/acp-schema.ts +1 -1
  529. package/src/config/assistant-feature-flags.ts +18 -142
  530. package/src/config/bundled-skills/acp/SKILL.md +44 -16
  531. package/src/config/bundled-skills/acp/TOOLS.json +45 -1
  532. package/src/config/bundled-skills/acp/tools/acp-list-agents.ts +12 -0
  533. package/src/config/bundled-skills/acp/tools/acp-steer.ts +12 -0
  534. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +14 -14
  535. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -4
  536. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +11 -6
  537. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +6 -6
  538. package/src/config/bundled-skills/media-processing/services/reduce.ts +0 -13
  539. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +1 -1
  540. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
  541. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -1
  542. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +1 -1
  543. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -1
  544. package/src/config/bundled-skills/settings/SKILL.md +2 -17
  545. package/src/config/bundled-skills/settings/TOOLS.json +0 -56
  546. package/src/config/bundled-skills/subagent/SKILL.md +2 -0
  547. package/src/config/bundled-tool-registry.ts +4 -6
  548. package/src/config/env.ts +7 -8
  549. package/src/config/feature-flag-registry.json +16 -24
  550. package/src/config/llm-resolver.ts +51 -33
  551. package/src/config/loader.ts +12 -15
  552. package/src/config/schema.ts +5 -72
  553. package/src/config/schemas/__tests__/filing.test.ts +58 -0
  554. package/src/config/schemas/__tests__/memory-v2.test.ts +186 -0
  555. package/src/config/schemas/filing.ts +12 -0
  556. package/src/config/schemas/host-browser.ts +2 -2
  557. package/src/config/schemas/inference.ts +0 -2
  558. package/src/config/schemas/ingress.ts +1 -1
  559. package/src/config/schemas/llm.ts +51 -9
  560. package/src/config/schemas/memory-storage.ts +1 -1
  561. package/src/config/schemas/memory-v2.ts +176 -0
  562. package/src/config/schemas/memory.ts +2 -0
  563. package/src/config/schemas/security.ts +0 -60
  564. package/src/config/schemas/services.ts +46 -7
  565. package/src/config/skills.ts +1 -1
  566. package/src/config/types.ts +0 -41
  567. package/src/contacts/contact-store.ts +2 -2
  568. package/src/contacts/contacts-write.ts +0 -38
  569. package/src/contacts/types.ts +8 -10
  570. package/src/context/token-estimator.ts +1 -1
  571. package/src/context/tool-result-truncation.ts +1 -1
  572. package/src/context/window-manager.ts +1 -1
  573. package/src/credential-execution/approval-bridge.ts +7 -69
  574. package/src/credential-execution/client.ts +17 -422
  575. package/src/credential-execution/feature-gates.ts +1 -2
  576. package/src/credential-execution/managed-catalog.ts +1 -1
  577. package/src/credential-health/credential-health-service.ts +1 -1
  578. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -13
  579. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
  580. package/src/daemon/__tests__/daemon-skill-host.test.ts +272 -0
  581. package/src/daemon/__tests__/meet-host-supervisor.test.ts +587 -0
  582. package/src/daemon/__tests__/meet-manifest-loader.test.ts +463 -0
  583. package/src/daemon/approval-generators.ts +2 -14
  584. package/src/daemon/classifier.ts +0 -106
  585. package/src/daemon/config-watcher.ts +14 -54
  586. package/src/daemon/connection-policy.ts +0 -14
  587. package/src/daemon/conversation-agent-loop-handlers.ts +37 -6
  588. package/src/daemon/conversation-agent-loop.ts +164 -53
  589. package/src/daemon/conversation-attachments.ts +5 -81
  590. package/src/daemon/conversation-error.ts +9 -5
  591. package/src/daemon/conversation-history.ts +1 -1
  592. package/src/daemon/conversation-launch.ts +1 -1
  593. package/src/daemon/conversation-messaging.ts +1 -1
  594. package/src/daemon/conversation-notifiers.ts +1 -1
  595. package/src/daemon/conversation-process.ts +9 -13
  596. package/src/daemon/conversation-runtime-assembly.ts +26 -88
  597. package/src/daemon/conversation-slash.ts +4 -160
  598. package/src/daemon/conversation-store.ts +368 -0
  599. package/src/daemon/conversation-surfaces.ts +5 -4
  600. package/src/daemon/conversation-tool-setup.ts +23 -172
  601. package/src/daemon/conversation.ts +46 -182
  602. package/src/daemon/daemon-control.ts +3 -3
  603. package/src/daemon/daemon-skill-host.ts +262 -0
  604. package/src/daemon/external-plugins-bootstrap.ts +67 -13
  605. package/src/daemon/handlers/config-channels.ts +2 -2
  606. package/src/daemon/handlers/config-embeddings.ts +1 -1
  607. package/src/daemon/handlers/config-ingress.ts +24 -2
  608. package/src/daemon/handlers/config-model.test.ts +17 -0
  609. package/src/daemon/handlers/config-model.ts +7 -52
  610. package/src/daemon/handlers/config-telegram.ts +6 -53
  611. package/src/daemon/handlers/config-voice.ts +1 -1
  612. package/src/daemon/handlers/conversations.ts +22 -156
  613. package/src/daemon/handlers/recording.ts +1 -1
  614. package/src/daemon/handlers/shared.ts +34 -35
  615. package/src/daemon/handlers/skills.ts +15 -23
  616. package/src/daemon/host-transfer-proxy.ts +500 -0
  617. package/src/daemon/lifecycle.ts +23 -258
  618. package/src/daemon/meet-host-startup.ts +51 -0
  619. package/src/daemon/meet-host-supervisor.ts +781 -0
  620. package/src/daemon/meet-manifest-loader.ts +410 -0
  621. package/src/daemon/memory-v2-startup.ts +35 -0
  622. package/src/daemon/message-protocol.ts +4 -7
  623. package/src/daemon/message-types/acp.ts +1 -0
  624. package/src/daemon/message-types/conversations.ts +16 -2
  625. package/src/daemon/message-types/host-transfer.ts +41 -0
  626. package/src/daemon/message-types/integrations.ts +6 -0
  627. package/src/daemon/message-types/messages.ts +14 -14
  628. package/src/daemon/message-types/schedules.ts +1 -0
  629. package/src/daemon/message-types/settings.ts +0 -6
  630. package/src/daemon/message-types/shared.ts +5 -2
  631. package/src/daemon/message-types/subagents.ts +2 -1
  632. package/src/daemon/message-types/workspace.ts +0 -2
  633. package/src/daemon/pkb-reminder-builder.test.ts +13 -12
  634. package/src/daemon/pkb-reminder-builder.ts +8 -16
  635. package/src/daemon/process-message.ts +616 -0
  636. package/src/daemon/providers-setup.ts +14 -6
  637. package/src/daemon/server.ts +79 -1274
  638. package/src/daemon/shutdown-handlers.ts +1 -1
  639. package/src/daemon/startup-error.ts +1 -1
  640. package/src/daemon/trust-context.ts +32 -0
  641. package/src/daemon/wake-target-adapter.ts +223 -0
  642. package/src/email/feature-gate.ts +1 -1
  643. package/src/events/domain-events.ts +1 -8
  644. package/src/events/tool-audit-listener.ts +2 -8
  645. package/src/events/tool-metrics-listener.ts +1 -4
  646. package/src/filing/filing-service.ts +194 -54
  647. package/src/followups/followup-store.ts +3 -71
  648. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +89 -21
  649. package/src/heartbeat/heartbeat-service.ts +32 -11
  650. package/src/home/__tests__/phase5-exit-criteria.test.ts +18 -1
  651. package/src/home/__tests__/rollup-producer.test.ts +67 -2
  652. package/src/home/assistant-feed-authoring.ts +8 -1
  653. package/src/home/feed-types.ts +1 -1
  654. package/src/home/relationship-state-writer.ts +1 -1
  655. package/src/home/rewrite-feed-title.ts +58 -0
  656. package/src/home/rollup-producer.ts +16 -3
  657. package/src/inbound/platform-callback-registration.ts +1 -17
  658. package/src/ipc/__tests__/attachment-ipc.test.ts +128 -66
  659. package/src/ipc/__tests__/browser-ipc.test.ts +75 -51
  660. package/src/ipc/__tests__/cache-ipc.test.ts +52 -107
  661. package/src/ipc/__tests__/cli-ipc.test.ts +9 -6
  662. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +254 -0
  663. package/src/ipc/__tests__/skill-server.test.ts +182 -0
  664. package/src/ipc/__tests__/socket-path.test.ts +69 -23
  665. package/src/ipc/__tests__/ui-request-route.test.ts +241 -216
  666. package/src/ipc/__tests__/watcher-ipc.test.ts +33 -33
  667. package/src/ipc/assistant-server.ts +450 -0
  668. package/src/ipc/cli-client.ts +3 -3
  669. package/src/ipc/gateway-client.test.ts +131 -0
  670. package/src/ipc/gateway-client.ts +98 -123
  671. package/src/ipc/ipc-framing.ts +281 -0
  672. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +152 -0
  673. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +219 -0
  674. package/src/ipc/routes/db-proxy.ts +73 -0
  675. package/src/ipc/routes/route-adapter.ts +32 -0
  676. package/src/ipc/routes/trust-rules.test.ts +218 -0
  677. package/src/ipc/skill-ipc-types.ts +13 -0
  678. package/src/ipc/skill-routes/__tests__/config.test.ts +146 -0
  679. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +402 -0
  680. package/src/ipc/skill-routes/__tests__/identity.test.ts +81 -0
  681. package/src/ipc/skill-routes/__tests__/log.test.ts +133 -0
  682. package/src/ipc/skill-routes/__tests__/memory.test.ts +178 -0
  683. package/src/ipc/skill-routes/__tests__/platform.test.ts +111 -0
  684. package/src/ipc/skill-routes/__tests__/providers.test.ts +265 -0
  685. package/src/ipc/skill-routes/__tests__/registries.test.ts +361 -0
  686. package/src/ipc/skill-routes/config.ts +47 -0
  687. package/src/ipc/skill-routes/events.ts +131 -0
  688. package/src/ipc/skill-routes/identity.ts +34 -0
  689. package/src/ipc/skill-routes/index.ts +37 -0
  690. package/src/ipc/skill-routes/log.ts +40 -0
  691. package/src/ipc/skill-routes/memory.ts +76 -0
  692. package/src/ipc/skill-routes/platform.ts +39 -0
  693. package/src/ipc/skill-routes/providers.ts +163 -0
  694. package/src/ipc/skill-routes/registries.ts +393 -0
  695. package/src/ipc/skill-server.ts +771 -0
  696. package/src/ipc/skill-socket-path.ts +20 -0
  697. package/src/ipc/socket-cleanup.ts +92 -0
  698. package/src/ipc/socket-path.ts +63 -32
  699. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +374 -0
  700. package/src/live-voice/__tests__/live-voice-archive.test.ts +525 -0
  701. package/src/live-voice/__tests__/live-voice-events.test.ts +473 -0
  702. package/src/live-voice/__tests__/live-voice-integration.test.ts +359 -0
  703. package/src/live-voice/__tests__/live-voice-metrics.test.ts +179 -0
  704. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +349 -0
  705. package/src/live-voice/__tests__/live-voice-stt.test.ts +244 -0
  706. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +337 -0
  707. package/src/live-voice/__tests__/live-voice-tts.test.ts +337 -0
  708. package/src/live-voice/__tests__/protocol.test.ts +295 -0
  709. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +421 -0
  710. package/src/live-voice/live-voice-archive.ts +758 -0
  711. package/src/live-voice/live-voice-metrics.ts +472 -0
  712. package/src/live-voice/live-voice-session-manager.ts +222 -0
  713. package/src/live-voice/live-voice-session.ts +1144 -0
  714. package/src/live-voice/live-voice-tts.ts +260 -0
  715. package/src/live-voice/protocol.ts +524 -0
  716. package/src/mcp/client.ts +2 -2
  717. package/src/media/types.ts +4 -4
  718. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +4 -28
  719. package/src/memory/__tests__/auto-analysis-guard.test.ts +2 -2
  720. package/src/memory/__tests__/conversation-analyze-job.test.ts +7 -62
  721. package/src/memory/__tests__/conversation-group-migration.test.ts +2 -2
  722. package/src/memory/__tests__/find-analysis-conversation.test.ts +2 -1
  723. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +235 -0
  724. package/src/memory/admin.ts +65 -7
  725. package/src/memory/app-git-service.ts +0 -14
  726. package/src/memory/attachments-store.ts +14 -16
  727. package/src/memory/auto-analysis-enqueue.ts +2 -17
  728. package/src/memory/canonical-guardian-store.ts +2 -1
  729. package/src/memory/channel-verification-sessions.ts +1 -1
  730. package/src/memory/checkpoints.ts +1 -1
  731. package/src/memory/context-search/agent-protocol.ts +424 -0
  732. package/src/memory/context-search/agent-runner.ts +1295 -0
  733. package/src/memory/context-search/format.ts +160 -0
  734. package/src/memory/context-search/limits.ts +106 -0
  735. package/src/memory/context-search/search.ts +387 -0
  736. package/src/memory/context-search/sources/conversations.ts +278 -0
  737. package/src/memory/context-search/sources/memory.ts +90 -0
  738. package/src/memory/context-search/sources/pkb.ts +468 -0
  739. package/src/memory/context-search/sources/workspace.ts +1255 -0
  740. package/src/memory/context-search/types.ts +49 -0
  741. package/src/memory/conversation-analyze-job.ts +3 -24
  742. package/src/memory/conversation-attention-store.ts +1 -1
  743. package/src/memory/conversation-bootstrap.ts +1 -1
  744. package/src/memory/conversation-crud.ts +69 -127
  745. package/src/memory/conversation-directories.ts +1 -11
  746. package/src/memory/conversation-display-order-migration.ts +11 -2
  747. package/src/memory/conversation-group-migration.ts +20 -4
  748. package/src/memory/conversation-key-store.ts +3 -4
  749. package/src/memory/conversation-queries.ts +13 -26
  750. package/src/memory/conversation-starter-validation.ts +88 -0
  751. package/src/memory/conversation-starters-cadence.ts +1 -1
  752. package/src/memory/conversation-title-service.ts +2 -1
  753. package/src/memory/db-init.ts +14 -4
  754. package/src/memory/db-maintenance.ts +1 -1
  755. package/src/memory/delivery-channels.ts +1 -14
  756. package/src/memory/delivery-crud.ts +2 -32
  757. package/src/memory/delivery-status.ts +1 -1
  758. package/src/memory/embedding-gemini.test.ts +4 -4
  759. package/src/memory/external-conversation-store.ts +1 -1
  760. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +412 -0
  761. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +225 -0
  762. package/src/memory/graph/bootstrap.test.ts +2 -7
  763. package/src/memory/graph/bootstrap.ts +2 -1
  764. package/src/memory/graph/capability-seed.ts +3 -3
  765. package/src/memory/graph/compaction.ts +1 -1
  766. package/src/memory/graph/consolidation.ts +13 -10
  767. package/src/memory/graph/conversation-graph-memory.ts +151 -1
  768. package/src/memory/graph/decay.ts +1 -1
  769. package/src/memory/graph/extraction.ts +53 -21
  770. package/src/memory/graph/graph-memory-state-store.ts +1 -1
  771. package/src/memory/graph/graph-search.test.ts +94 -2
  772. package/src/memory/graph/graph-search.ts +22 -7
  773. package/src/memory/graph/image-ref-utils.ts +1 -1
  774. package/src/memory/graph/retriever.test.ts +158 -4
  775. package/src/memory/graph/retriever.ts +17 -5
  776. package/src/memory/graph/store.test.ts +2 -1
  777. package/src/memory/graph/store.ts +1 -1
  778. package/src/memory/graph/tool-handlers.ts +73 -247
  779. package/src/memory/graph/tools.ts +35 -53
  780. package/src/memory/group-crud.ts +1 -2
  781. package/src/memory/guardian-action-store.ts +2 -1
  782. package/src/memory/guardian-approvals.ts +1 -1
  783. package/src/memory/guardian-rate-limits.ts +1 -1
  784. package/src/memory/indexer.ts +43 -17
  785. package/src/memory/invite-store.ts +1 -1
  786. package/src/memory/job-handlers/backfill.ts +1 -1
  787. package/src/memory/job-handlers/cleanup.ts +2 -1
  788. package/src/memory/job-handlers/conversation-starters.ts +18 -10
  789. package/src/memory/job-handlers/embedding.test.ts +2 -1
  790. package/src/memory/job-handlers/embedding.ts +1 -1
  791. package/src/memory/job-handlers/index-maintenance.ts +1 -1
  792. package/src/memory/job-handlers/summarization.ts +3 -3
  793. package/src/memory/job-utils.ts +3 -3
  794. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +362 -0
  795. package/src/memory/jobs/embed-concept-page.ts +210 -0
  796. package/src/memory/jobs/embed-pkb-file.test.ts +2 -1
  797. package/src/memory/jobs-store.ts +10 -2
  798. package/src/memory/jobs-worker.ts +58 -5
  799. package/src/memory/lifecycle-events-store.ts +1 -1
  800. package/src/memory/llm-request-log-store.ts +1 -1
  801. package/src/memory/llm-usage-store.ts +1 -1
  802. package/src/memory/media-store.ts +1 -1
  803. package/src/memory/memory-recall-log-store.ts +1 -1
  804. package/src/memory/migrations/038-actor-token-records.ts +3 -0
  805. package/src/memory/migrations/039-actor-refresh-token-records.ts +3 -0
  806. package/src/memory/migrations/226-schedule-wake-conversation-id.ts +11 -0
  807. package/src/memory/migrations/227-add-conversation-inference-profile.ts +18 -0
  808. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +27 -0
  809. package/src/memory/migrations/229-delete-private-conversations.test.ts +1087 -0
  810. package/src/memory/migrations/229-delete-private-conversations.ts +210 -0
  811. package/src/memory/migrations/230-acp-session-history.ts +41 -0
  812. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +128 -0
  813. package/src/memory/migrations/232-activation-state.ts +38 -0
  814. package/src/memory/migrations/index.ts +10 -0
  815. package/src/memory/migrations/registry.ts +7 -0
  816. package/src/memory/pkb/pkb-index.test.ts +4 -5
  817. package/src/memory/pkb/pkb-reconcile.test.ts +4 -5
  818. package/src/memory/pkb/pkb-search.test.ts +83 -3
  819. package/src/memory/pkb/pkb-search.ts +27 -14
  820. package/src/memory/published-pages-store.ts +1 -1
  821. package/src/memory/schema/acp.ts +30 -0
  822. package/src/memory/schema/conversations.ts +1 -1
  823. package/src/memory/schema/index.ts +1 -0
  824. package/src/memory/schema/infrastructure.ts +1 -32
  825. package/src/memory/schema/memory-graph.ts +36 -14
  826. package/src/memory/scoped-approval-grants.ts +2 -1
  827. package/src/memory/search/semantic.ts +2 -2
  828. package/src/memory/shared-app-links-store.ts +2 -1
  829. package/src/memory/tool-usage-store.ts +1 -1
  830. package/src/memory/trace-event-store.ts +2 -1
  831. package/src/memory/turn-events-store.ts +1 -1
  832. package/src/memory/v2/__tests__/activation-store.test.ts +202 -0
  833. package/src/memory/v2/__tests__/activation.test.ts +956 -0
  834. package/src/memory/v2/__tests__/backfill-jobs.test.ts +610 -0
  835. package/src/memory/v2/__tests__/consolidation-job.test.ts +395 -0
  836. package/src/memory/v2/__tests__/edges.test.ts +435 -0
  837. package/src/memory/v2/__tests__/injection.test.ts +792 -0
  838. package/src/memory/v2/__tests__/migration.test.ts +812 -0
  839. package/src/memory/v2/__tests__/page-store.test.ts +334 -0
  840. package/src/memory/v2/__tests__/qdrant.test.ts +438 -0
  841. package/src/memory/v2/__tests__/sim.test.ts +549 -0
  842. package/src/memory/v2/__tests__/skill-content.test.ts +85 -0
  843. package/src/memory/v2/__tests__/skill-qdrant.test.ts +657 -0
  844. package/src/memory/v2/__tests__/skill-store.test.ts +351 -0
  845. package/src/memory/v2/__tests__/sweep-job.test.ts +441 -0
  846. package/src/memory/v2/activation-store.ts +109 -0
  847. package/src/memory/v2/activation.ts +490 -0
  848. package/src/memory/v2/backfill-jobs.ts +442 -0
  849. package/src/memory/v2/consolidation-job.ts +304 -0
  850. package/src/memory/v2/edges.ts +217 -0
  851. package/src/memory/v2/injection.ts +307 -0
  852. package/src/memory/v2/migration.ts +654 -0
  853. package/src/memory/v2/now-text.ts +38 -0
  854. package/src/memory/v2/page-store.ts +245 -0
  855. package/src/memory/v2/prompts/consolidation.ts +185 -0
  856. package/src/memory/v2/prompts/sweep.ts +56 -0
  857. package/src/memory/v2/qdrant.ts +342 -0
  858. package/src/memory/v2/sim.ts +206 -0
  859. package/src/memory/v2/skill-content.ts +42 -0
  860. package/src/memory/v2/skill-qdrant.ts +395 -0
  861. package/src/memory/v2/skill-store.ts +128 -0
  862. package/src/memory/v2/sweep-job.ts +298 -0
  863. package/src/memory/v2/types.ts +116 -0
  864. package/src/memory/validation.ts +1 -1
  865. package/src/messaging/providers/index.ts +262 -0
  866. package/src/messaging/providers/slack/api.ts +242 -0
  867. package/src/messaging/providers/slack/message-metadata.ts +1 -1
  868. package/src/messaging/providers/slack/send.ts +383 -0
  869. package/src/messaging/providers/telegram-bot/adapter.ts +4 -42
  870. package/src/messaging/providers/telegram-bot/api.ts +253 -0
  871. package/src/messaging/providers/telegram-bot/client.ts +17 -58
  872. package/src/messaging/providers/telegram-bot/send.ts +232 -0
  873. package/src/messaging/providers/whatsapp/adapter.ts +4 -36
  874. package/src/messaging/providers/whatsapp/api.ts +319 -0
  875. package/src/messaging/providers/whatsapp/client.ts +4 -48
  876. package/src/messaging/providers/whatsapp/send.ts +209 -0
  877. package/src/notifications/adapters/slack.ts +5 -23
  878. package/src/notifications/adapters/telegram.ts +8 -29
  879. package/src/notifications/conversation-candidates.ts +1 -1
  880. package/src/notifications/conversation-seed-composer.ts +12 -6
  881. package/src/notifications/copy-composer.ts +1 -1
  882. package/src/notifications/decision-engine.ts +1 -1
  883. package/src/notifications/decisions-store.ts +1 -1
  884. package/src/notifications/deliveries-store.ts +2 -1
  885. package/src/notifications/deterministic-checks.ts +1 -1
  886. package/src/notifications/events-store.ts +1 -13
  887. package/src/notifications/preferences-store.ts +1 -1
  888. package/src/notifications/signal.ts +0 -9
  889. package/src/oauth/connection-resolver.ts +11 -2
  890. package/src/oauth/oauth-store.ts +2 -1
  891. package/src/outbound-proxy/index.ts +0 -1
  892. package/src/permissions/approval-policy.test.ts +149 -132
  893. package/src/permissions/approval-policy.ts +65 -91
  894. package/src/permissions/checker.test.ts +632 -0
  895. package/src/permissions/checker.ts +266 -459
  896. package/src/permissions/gateway-threshold-reader.ts +28 -47
  897. package/src/permissions/ipc-risk-types.ts +95 -0
  898. package/src/permissions/prompter.ts +4 -9
  899. package/src/permissions/risk-types.ts +24 -210
  900. package/src/permissions/types.ts +17 -47
  901. package/src/permissions/workspace-policy.ts +2 -4
  902. package/src/playbooks/playbook-compiler.ts +1 -1
  903. package/src/plugins/defaults/index.ts +1 -1
  904. package/src/plugins/defaults/injectors.ts +18 -21
  905. package/src/plugins/defaults/llm-call.ts +6 -9
  906. package/src/plugins/defaults/memory-retrieval.ts +1 -6
  907. package/src/plugins/defaults/overflow-reduce.ts +9 -5
  908. package/src/plugins/defaults/token-estimate.ts +2 -3
  909. package/src/plugins/registry.ts +61 -1
  910. package/src/plugins/types.ts +6 -7
  911. package/src/plugins/user-loader.ts +36 -10
  912. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +197 -0
  913. package/src/prompts/persona-resolver.ts +2 -4
  914. package/src/prompts/system-prompt.ts +39 -0
  915. package/src/prompts/templates/SOUL.md +3 -1
  916. package/src/providers/__tests__/provider-env-vars.test.ts +0 -21
  917. package/src/providers/__tests__/retry-callsite.test.ts +3 -6
  918. package/src/providers/anthropic/client.ts +71 -19
  919. package/src/providers/call-site-routing.ts +7 -3
  920. package/src/providers/fireworks/client.ts +3 -0
  921. package/src/providers/gemini/client.ts +96 -22
  922. package/src/providers/managed-proxy/context.ts +0 -12
  923. package/src/providers/model-catalog.ts +83 -8
  924. package/src/providers/model-intents.ts +7 -8
  925. package/src/providers/openai/chat-completions-provider.ts +37 -7
  926. package/src/providers/openai/responses-provider.ts +39 -4
  927. package/src/providers/openrouter/client.ts +4 -5
  928. package/src/providers/provider-env-vars.ts +4 -12
  929. package/src/providers/provider-send-message.ts +16 -11
  930. package/src/providers/registry.ts +1 -1
  931. package/src/providers/retry.ts +52 -23
  932. package/src/providers/speech-to-text/openai-whisper-stream.ts +1 -1
  933. package/src/providers/speech-to-text/openai-whisper.ts +3 -6
  934. package/src/providers/speech-to-text/provider-catalog.ts +75 -0
  935. package/src/providers/speech-to-text/xai.ts +5 -5
  936. package/src/providers/thinking-config.ts +34 -0
  937. package/src/providers/types.ts +22 -10
  938. package/src/runtime/AGENTS.md +10 -9
  939. package/src/runtime/__tests__/agent-wake.test.ts +33 -9
  940. package/src/runtime/__tests__/client-registry.test.ts +5 -27
  941. package/src/runtime/__tests__/interactive-ui.test.ts +157 -246
  942. package/src/runtime/access-request-helper.ts +9 -20
  943. package/src/runtime/actor-trust-resolver.ts +2 -2
  944. package/src/runtime/agent-wake.ts +174 -68
  945. package/src/runtime/approval-conversation-turn.ts +2 -15
  946. package/src/runtime/approval-message-composer.ts +11 -60
  947. package/src/runtime/assistant-event.ts +18 -66
  948. package/src/runtime/auth/__tests__/guard-tests.test.ts +6 -30
  949. package/src/runtime/auth/__tests__/middleware.test.ts +10 -10
  950. package/src/runtime/auth/__tests__/route-policy.test.ts +0 -8
  951. package/src/runtime/auth/context.ts +9 -0
  952. package/src/runtime/auth/middleware.ts +4 -4
  953. package/src/runtime/auth/route-policy.ts +195 -4
  954. package/src/runtime/auth/token-service.ts +1 -100
  955. package/src/runtime/capability-tokens.ts +89 -313
  956. package/src/runtime/channel-approval-types.ts +1 -6
  957. package/src/runtime/channel-approvals.ts +7 -79
  958. package/src/runtime/channel-readiness-service.ts +2 -2
  959. package/src/runtime/channel-reply-delivery.ts +2 -8
  960. package/src/runtime/channel-retry-sweep.ts +20 -17
  961. package/src/runtime/client-registry.ts +21 -28
  962. package/src/runtime/confirmation-request-guardian-bridge.ts +2 -7
  963. package/src/runtime/gateway-client.ts +37 -378
  964. package/src/runtime/guardian-action-grant-minter.ts +2 -3
  965. package/src/runtime/guardian-action-message-composer.ts +11 -52
  966. package/src/runtime/guardian-action-service.ts +19 -7
  967. package/src/runtime/guardian-decision-types.ts +4 -65
  968. package/src/runtime/guardian-reply-router.ts +10 -19
  969. package/src/runtime/guardian-vellum-migration.ts +5 -64
  970. package/src/runtime/http-errors.ts +3 -0
  971. package/src/runtime/http-router.ts +50 -7
  972. package/src/runtime/http-server.ts +345 -1110
  973. package/src/runtime/http-types.ts +15 -98
  974. package/src/runtime/interactive-ui-types.ts +145 -0
  975. package/src/runtime/interactive-ui.ts +38 -196
  976. package/src/runtime/invite-redemption-service.ts +1 -1
  977. package/src/runtime/invite-redemption-templates.ts +1 -1
  978. package/src/runtime/local-actor-identity.ts +13 -43
  979. package/src/runtime/message-composer-types.ts +134 -0
  980. package/src/runtime/middleware/rate-limiter.ts +1 -1
  981. package/src/runtime/middleware/request-logger.ts +5 -2
  982. package/src/runtime/migrations/__tests__/job-registry.test.ts +346 -0
  983. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +16 -0
  984. package/src/runtime/migrations/job-registry.ts +281 -0
  985. package/src/runtime/migrations/vbundle-builder.ts +3 -4
  986. package/src/runtime/migrations/vbundle-importer.ts +1 -1
  987. package/src/runtime/migrations/vbundle-streaming-importer.ts +0 -13
  988. package/src/runtime/migrations/vbundle-tar-stream.ts +11 -3
  989. package/src/runtime/nl-approval-parser.ts +16 -21
  990. package/src/runtime/pending-interactions.ts +29 -12
  991. package/src/runtime/routes/__tests__/acp-routes.test.ts +395 -0
  992. package/src/runtime/routes/__tests__/backup-routes.test.ts +204 -320
  993. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +72 -4
  994. package/src/runtime/routes/__tests__/stt-routes.test.ts +182 -223
  995. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +230 -0
  996. package/src/{ipc/__tests__/task-ipc.test.ts → runtime/routes/__tests__/task-routes.test.ts} +116 -96
  997. package/src/runtime/routes/__tests__/tts-routes.test.ts +185 -289
  998. package/src/runtime/routes/access-request-decision.ts +25 -50
  999. package/src/runtime/routes/acp-routes.test.ts +371 -0
  1000. package/src/runtime/routes/acp-routes.ts +392 -166
  1001. package/src/runtime/routes/app-management-routes.ts +464 -660
  1002. package/src/runtime/routes/app-routes.ts +192 -177
  1003. package/src/runtime/routes/approval-routes.ts +116 -434
  1004. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +24 -84
  1005. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +3 -10
  1006. package/src/runtime/routes/attachment-routes.ts +409 -253
  1007. package/src/runtime/routes/audio-routes.ts +51 -18
  1008. package/src/runtime/routes/avatar-routes.ts +82 -75
  1009. package/src/runtime/routes/background-tool-routes.ts +94 -0
  1010. package/src/runtime/routes/backup-routes.ts +154 -336
  1011. package/src/runtime/routes/brain-graph-routes.ts +83 -110
  1012. package/src/runtime/routes/browser-routes.ts +141 -0
  1013. package/src/runtime/routes/btw-routes.ts +62 -106
  1014. package/src/runtime/routes/cache-routes.ts +96 -0
  1015. package/src/runtime/routes/call-routes.ts +208 -247
  1016. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +1 -1
  1017. package/src/runtime/routes/channel-delivery-routes.ts +25 -27
  1018. package/src/runtime/routes/channel-readiness-routes.ts +83 -120
  1019. package/src/runtime/routes/channel-route-definitions.ts +62 -0
  1020. package/src/runtime/routes/channel-route-shared.ts +14 -18
  1021. package/src/runtime/routes/channel-verification-routes.ts +207 -187
  1022. package/src/runtime/routes/client-routes.ts +48 -0
  1023. package/src/runtime/routes/contact-routes.ts +533 -407
  1024. package/src/runtime/routes/conversation-analysis-routes.ts +48 -49
  1025. package/src/runtime/routes/conversation-attention-routes.ts +55 -67
  1026. package/src/runtime/routes/conversation-list-routes.ts +265 -0
  1027. package/src/runtime/routes/conversation-management-routes.ts +626 -715
  1028. package/src/runtime/routes/conversation-query-routes.ts +510 -460
  1029. package/src/runtime/routes/conversation-routes.ts +456 -368
  1030. package/src/runtime/routes/conversation-starter-routes.ts +121 -71
  1031. package/src/runtime/routes/credential-prompt-routes.ts +124 -0
  1032. package/src/runtime/routes/debug-routes.ts +34 -39
  1033. package/src/runtime/routes/defer-routes.ts +230 -0
  1034. package/src/runtime/routes/diagnostics-routes.ts +79 -70
  1035. package/src/runtime/routes/documents-routes.ts +117 -106
  1036. package/src/runtime/routes/errors.ts +132 -0
  1037. package/src/runtime/routes/events-routes.ts +97 -58
  1038. package/src/runtime/routes/filing-routes.ts +65 -78
  1039. package/src/runtime/routes/global-search-routes.ts +51 -57
  1040. package/src/runtime/routes/group-routes.ts +199 -181
  1041. package/src/runtime/routes/guardian-action-routes.ts +103 -169
  1042. package/src/runtime/routes/guardian-approval-interception.ts +27 -58
  1043. package/src/runtime/routes/guardian-approval-prompt.ts +10 -21
  1044. package/src/runtime/routes/guardian-approval-reply-helpers.ts +2 -6
  1045. package/src/runtime/routes/guardian-expiry-sweep.ts +19 -36
  1046. package/src/runtime/routes/heartbeat-routes.ts +194 -209
  1047. package/src/runtime/routes/home-feed-routes.ts +85 -187
  1048. package/src/runtime/routes/home-state-routes.ts +27 -24
  1049. package/src/runtime/routes/host-bash-routes.ts +42 -52
  1050. package/src/runtime/routes/host-browser-routes.ts +38 -69
  1051. package/src/runtime/routes/host-cu-routes.ts +74 -70
  1052. package/src/runtime/routes/host-file-routes.ts +50 -60
  1053. package/src/runtime/routes/host-transfer-routes.ts +220 -0
  1054. package/src/runtime/routes/http-adapter.ts +172 -0
  1055. package/src/runtime/routes/identity-routes.ts +83 -79
  1056. package/src/runtime/routes/inbound-conversation.ts +11 -18
  1057. package/src/runtime/routes/inbound-message-handler.ts +74 -110
  1058. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +79 -138
  1059. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +2 -3
  1060. package/src/runtime/routes/inbound-stages/background-dispatch.ts +54 -90
  1061. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +25 -50
  1062. package/src/runtime/routes/inbound-stages/edit-intercept.ts +7 -7
  1063. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
  1064. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +5 -6
  1065. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -24
  1066. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -10
  1067. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
  1068. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +3 -3
  1069. package/src/runtime/routes/inbound-stages/verification-intercept.ts +19 -26
  1070. package/src/runtime/routes/index.ts +197 -0
  1071. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +25 -32
  1072. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +22 -31
  1073. package/src/runtime/routes/integrations/slack/channel.ts +69 -66
  1074. package/src/runtime/routes/integrations/slack/share.ts +49 -58
  1075. package/src/runtime/routes/integrations/telegram.ts +91 -74
  1076. package/src/runtime/routes/integrations/twilio.ts +163 -240
  1077. package/src/runtime/routes/integrations/vercel.ts +57 -54
  1078. package/src/runtime/routes/interface-routes.ts +43 -0
  1079. package/src/runtime/routes/internal-oauth-routes.ts +56 -0
  1080. package/src/runtime/routes/internal-twilio-routes.ts +46 -0
  1081. package/src/runtime/routes/llm-context-normalization.ts +4 -2
  1082. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  1083. package/src/runtime/routes/log-export-routes.ts +90 -100
  1084. package/src/runtime/routes/memory-item-routes.test.ts +152 -175
  1085. package/src/runtime/routes/memory-item-routes.ts +243 -323
  1086. package/src/runtime/routes/memory-v2-routes.ts +193 -0
  1087. package/src/runtime/routes/migration-rollback-routes.ts +167 -212
  1088. package/src/runtime/routes/migration-routes.ts +877 -374
  1089. package/src/runtime/routes/notification-routes.ts +199 -70
  1090. package/src/runtime/routes/oauth-apps.ts +254 -251
  1091. package/src/runtime/routes/oauth-providers.ts +66 -57
  1092. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +60 -120
  1093. package/src/runtime/routes/playground/__tests__/guard.test.ts +34 -54
  1094. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +107 -151
  1095. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +41 -117
  1096. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +95 -138
  1097. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +115 -217
  1098. package/src/runtime/routes/playground/__tests__/state.test.ts +41 -90
  1099. package/src/runtime/routes/playground/conversation-not-found.ts +9 -11
  1100. package/src/runtime/routes/playground/force-compact.ts +41 -54
  1101. package/src/runtime/routes/playground/guard.ts +18 -19
  1102. package/src/runtime/routes/playground/helpers.ts +103 -0
  1103. package/src/runtime/routes/playground/index.ts +15 -25
  1104. package/src/runtime/routes/playground/inject-failures.ts +48 -64
  1105. package/src/runtime/routes/playground/reset-circuit.ts +31 -57
  1106. package/src/runtime/routes/playground/seed-conversation.ts +66 -92
  1107. package/src/runtime/routes/playground/seeded-conversations.ts +60 -64
  1108. package/src/runtime/routes/playground/state.ts +23 -24
  1109. package/src/runtime/routes/profiler-routes.ts +132 -167
  1110. package/src/runtime/routes/ps-routes.ts +120 -0
  1111. package/src/runtime/routes/recording-routes.ts +197 -258
  1112. package/src/runtime/routes/rename-conversation-routes.ts +89 -0
  1113. package/src/runtime/routes/schedule-routes.ts +238 -242
  1114. package/src/runtime/routes/secret-routes.ts +219 -265
  1115. package/src/runtime/routes/secrets-deps.ts +24 -0
  1116. package/src/runtime/routes/settings-routes.ts +361 -441
  1117. package/src/runtime/routes/skills-routes.ts +434 -469
  1118. package/src/runtime/routes/stt-routes.ts +196 -206
  1119. package/src/runtime/routes/subagents-routes.ts +125 -141
  1120. package/src/runtime/routes/suggest-trust-rule-routes.ts +244 -0
  1121. package/src/runtime/routes/surface-action-routes.ts +135 -190
  1122. package/src/runtime/routes/surface-content-routes.ts +84 -118
  1123. package/src/runtime/routes/task-routes.ts +354 -0
  1124. package/src/runtime/routes/telemetry-routes.ts +33 -49
  1125. package/src/runtime/routes/trace-event-routes.ts +55 -74
  1126. package/src/runtime/routes/trust-rules-routes.ts +147 -239
  1127. package/src/runtime/routes/tts-routes.ts +187 -169
  1128. package/src/runtime/routes/types.ts +139 -0
  1129. package/src/{ipc/routes/ui-request.ts → runtime/routes/ui-request-routes.ts} +23 -17
  1130. package/src/runtime/routes/upgrade-broadcast-routes.ts +156 -197
  1131. package/src/runtime/routes/usage-routes.ts +143 -169
  1132. package/src/runtime/routes/user-routes.ts +102 -18
  1133. package/src/runtime/routes/wake-conversation-routes.ts +49 -0
  1134. package/src/{ipc/routes/watcher.ts → runtime/routes/watcher-routes.ts} +84 -39
  1135. package/src/runtime/routes/wipe-conversation-routes.ts +89 -0
  1136. package/src/runtime/routes/work-items-routes.test.ts +10 -20
  1137. package/src/runtime/routes/work-items-routes.ts +418 -433
  1138. package/src/runtime/routes/workspace-commit-routes.ts +30 -61
  1139. package/src/runtime/routes/workspace-routes.test.ts +254 -381
  1140. package/src/runtime/routes/workspace-routes.ts +238 -246
  1141. package/src/runtime/runtime-mode.ts +8 -1
  1142. package/src/runtime/services/__tests__/analyze-conversation.test.ts +80 -118
  1143. package/src/runtime/services/analyze-conversation.ts +14 -41
  1144. package/src/runtime/services/conversation-serializer.ts +181 -0
  1145. package/src/runtime/trust-context-resolver.ts +3 -2
  1146. package/src/runtime/verification-outbound-actions.ts +13 -49
  1147. package/src/schedule/schedule-store.ts +64 -2
  1148. package/src/schedule/scheduler.ts +101 -0
  1149. package/src/security/ces-credential-client.ts +32 -169
  1150. package/src/security/ces-rpc-credential-backend.ts +1 -1
  1151. package/src/security/credential-backend.ts +6 -6
  1152. package/src/security/oauth-completion-page.ts +1 -1
  1153. package/src/security/oauth2.ts +3 -6
  1154. package/src/sequence/analytics.ts +1 -1
  1155. package/src/sequence/guardrails.ts +3 -3
  1156. package/src/sequence/store.ts +2 -1
  1157. package/src/signals/bash.ts +1 -1
  1158. package/src/signals/event-stream.ts +1 -1
  1159. package/src/skills/catalog-cache.ts +7 -0
  1160. package/src/skills/catalog-files.ts +0 -5
  1161. package/src/skills/catalog-install.ts +28 -18
  1162. package/src/skills/category-inference.ts +0 -11
  1163. package/src/skills/clawhub.ts +2 -2
  1164. package/src/skills/managed-store.ts +2 -2
  1165. package/src/skills/remote-skill-policy.ts +6 -7
  1166. package/src/subagent/index.ts +2 -6
  1167. package/src/subagent/manager.ts +27 -23
  1168. package/src/subagent/types.ts +9 -0
  1169. package/src/tasks/SPEC.md +2 -2
  1170. package/src/tasks/task-compiler.ts +1 -1
  1171. package/src/tasks/task-runner.ts +2 -22
  1172. package/src/tasks/task-store.ts +1 -1
  1173. package/src/tools/acp/list-agents.test.ts +115 -0
  1174. package/src/tools/acp/list-agents.ts +31 -0
  1175. package/src/tools/acp/spawn.test.ts +379 -0
  1176. package/src/tools/acp/spawn.ts +142 -62
  1177. package/src/tools/acp/steer.test.ts +101 -0
  1178. package/src/tools/acp/steer.ts +38 -0
  1179. package/src/tools/background-tool-registry.ts +98 -0
  1180. package/src/tools/browser/browser-execution.ts +34 -7
  1181. package/src/tools/browser/browser-manager.ts +1 -8
  1182. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +1 -1
  1183. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +3 -1
  1184. package/src/tools/browser/cdp-client/types.ts +4 -1
  1185. package/src/tools/computer-use/definitions.ts +1 -1
  1186. package/src/tools/credential-execution/make-authenticated-request.ts +2 -2
  1187. package/src/tools/credential-execution/manage-secure-command-tool.ts +1 -1
  1188. package/src/tools/credential-execution/run-authenticated-command.ts +2 -2
  1189. package/src/tools/credentials/broker-types.ts +2 -1
  1190. package/src/tools/document/editor-template.ts +1 -1
  1191. package/src/tools/execution-timeout.ts +1 -1
  1192. package/src/tools/executor.ts +10 -15
  1193. package/src/tools/host-filesystem/transfer.test.ts +268 -0
  1194. package/src/tools/host-filesystem/transfer.ts +234 -0
  1195. package/src/tools/host-terminal/host-shell.ts +189 -11
  1196. package/src/tools/mcp/mcp-tool-factory.ts +1 -1
  1197. package/src/tools/memory/register.test.ts +161 -1
  1198. package/src/tools/memory/register.ts +19 -34
  1199. package/src/tools/permission-checker.ts +18 -219
  1200. package/src/tools/policy-context.ts +1 -8
  1201. package/src/tools/registry.ts +16 -1
  1202. package/src/tools/secret-detection-handler.ts +13 -103
  1203. package/src/tools/shared/shell-output.ts +4 -1
  1204. package/src/tools/side-effects.ts +2 -2
  1205. package/src/tools/skills/execute.ts +1 -1
  1206. package/src/tools/subagent/spawn.ts +35 -11
  1207. package/src/tools/terminal/safe-env.ts +9 -1
  1208. package/src/tools/terminal/shell.ts +161 -31
  1209. package/src/tools/tool-approval-handler.ts +4 -70
  1210. package/src/tools/tool-input-summary.ts +10 -0
  1211. package/src/tools/types.ts +143 -163
  1212. package/src/tools/ui-surface/definitions.ts +2 -2
  1213. package/src/util/debounce.ts +0 -21
  1214. package/src/util/errors.ts +0 -8
  1215. package/src/util/log-redact.ts +0 -1
  1216. package/src/util/platform.ts +85 -124
  1217. package/src/util/pricing.ts +109 -6
  1218. package/src/watcher/engine.ts +42 -20
  1219. package/src/watcher/watcher-store.ts +2 -1
  1220. package/src/work-items/work-item-store.ts +1 -1
  1221. package/src/workspace/git-service.ts +1 -6
  1222. package/src/workspace/migrations/006-services-config.ts +10 -1
  1223. package/src/workspace/migrations/017-seed-persona-dirs.ts +1 -1
  1224. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +1 -1
  1225. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +1 -1
  1226. package/src/workspace/migrations/031-drop-user-md.ts +1 -1
  1227. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +3 -4
  1228. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +150 -0
  1229. package/src/workspace/migrations/053-release-notes-acp-codex.ts +107 -0
  1230. package/src/workspace/migrations/054-seed-recall-callsite.ts +102 -0
  1231. package/src/workspace/migrations/055-release-notes-agentic-recall.ts +63 -0
  1232. package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +65 -0
  1233. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +98 -0
  1234. package/src/workspace/migrations/058-release-notes-acp-sessions-ui.ts +71 -0
  1235. package/src/workspace/migrations/059-move-pid-to-workspace.ts +53 -0
  1236. package/src/workspace/migrations/060-memory-v2-init.ts +53 -0
  1237. package/src/workspace/migrations/rebuild-conversation-disk-view.ts +1 -1
  1238. package/src/workspace/migrations/registry.ts +18 -0
  1239. package/src/workspace/migrations/runner.ts +2 -2
  1240. package/src/workspace/provider-commit-message-generator.ts +1 -1
  1241. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +0 -471
  1242. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +0 -436
  1243. package/src/__tests__/cli-command-risk-guard.test.ts +0 -368
  1244. package/src/__tests__/config-watcher-feature-flags.test.ts +0 -211
  1245. package/src/__tests__/conversation-approval-overrides.test.ts +0 -207
  1246. package/src/__tests__/conversation-host-access-routes.test.ts +0 -229
  1247. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +0 -226
  1248. package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +0 -167
  1249. package/src/__tests__/ephemeral-permissions.test.ts +0 -474
  1250. package/src/__tests__/extension-id-sync-guard.test.ts +0 -241
  1251. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +0 -374
  1252. package/src/__tests__/native-host-marker-sync-guard.test.ts +0 -157
  1253. package/src/__tests__/pairing-concurrent.test.ts +0 -84
  1254. package/src/__tests__/pairing-routes.test.ts +0 -181
  1255. package/src/__tests__/parser.test.ts +0 -595
  1256. package/src/__tests__/permission-checker-host-gate.test.ts +0 -488
  1257. package/src/__tests__/permission-controls-v2-flag.test.ts +0 -55
  1258. package/src/__tests__/permission-mode.test.ts +0 -89
  1259. package/src/__tests__/provider-env-vars-scope.test.ts +0 -52
  1260. package/src/__tests__/risk-classifier-parity.test.ts +0 -230
  1261. package/src/__tests__/shell-identity.test.ts +0 -236
  1262. package/src/__tests__/shell-parser-fuzz.test.ts +0 -629
  1263. package/src/__tests__/shell-parser-property.test.ts +0 -936
  1264. package/src/__tests__/starter-bundle.test.ts +0 -173
  1265. package/src/__tests__/stt-catalog-parity.test.ts +0 -282
  1266. package/src/__tests__/task-runner.test.ts +0 -224
  1267. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -354
  1268. package/src/__tests__/trust-store-pattern-matches.test.ts +0 -29
  1269. package/src/__tests__/trust-store.test.ts +0 -2013
  1270. package/src/__tests__/v2-consent-policy.test.ts +0 -103
  1271. package/src/browser/identifiers.ts +0 -51
  1272. package/src/cli/db.ts +0 -1
  1273. package/src/config/bundled-skills/settings/tools/avatar-get.ts +0 -40
  1274. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +0 -64
  1275. package/src/config/bundled-skills/settings/tools/avatar-update.ts +0 -88
  1276. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +0 -127
  1277. package/src/daemon/approved-devices-store.ts +0 -110
  1278. package/src/daemon/external-skills-bootstrap.ts +0 -41
  1279. package/src/daemon/message-types/trust.ts +0 -71
  1280. package/src/daemon/pairing-store.ts +0 -229
  1281. package/src/ipc/cli-server.ts +0 -252
  1282. package/src/ipc/routes/attachment.ts +0 -114
  1283. package/src/ipc/routes/browser-context.ts +0 -63
  1284. package/src/ipc/routes/browser.ts +0 -97
  1285. package/src/ipc/routes/cache.ts +0 -96
  1286. package/src/ipc/routes/get-contact.ts +0 -16
  1287. package/src/ipc/routes/index.ts +0 -35
  1288. package/src/ipc/routes/list-clients.ts +0 -31
  1289. package/src/ipc/routes/merge-contacts.ts +0 -17
  1290. package/src/ipc/routes/notification.ts +0 -133
  1291. package/src/ipc/routes/rename-conversation.ts +0 -59
  1292. package/src/ipc/routes/search-contacts.ts +0 -19
  1293. package/src/ipc/routes/task-queue.ts +0 -226
  1294. package/src/ipc/routes/task.ts +0 -173
  1295. package/src/ipc/routes/upsert-contact.ts +0 -25
  1296. package/src/ipc/routes/wake-conversation.ts +0 -19
  1297. package/src/memory/db.ts +0 -23
  1298. package/src/permissions/arg-parser.test.ts +0 -161
  1299. package/src/permissions/arg-parser.ts +0 -141
  1300. package/src/permissions/bash-risk-classifier.test.ts +0 -1620
  1301. package/src/permissions/bash-risk-classifier.ts +0 -950
  1302. package/src/permissions/command-registry.test.ts +0 -774
  1303. package/src/permissions/command-registry.ts +0 -1005
  1304. package/src/permissions/defaults.ts +0 -314
  1305. package/src/permissions/file-risk-classifier.test.ts +0 -535
  1306. package/src/permissions/file-risk-classifier.ts +0 -274
  1307. package/src/permissions/permission-mode.ts +0 -24
  1308. package/src/permissions/schedule-risk-classifier.test.ts +0 -129
  1309. package/src/permissions/schedule-risk-classifier.ts +0 -85
  1310. package/src/permissions/shell-identity.ts +0 -297
  1311. package/src/permissions/skill-risk-classifier.test.ts +0 -311
  1312. package/src/permissions/skill-risk-classifier.ts +0 -214
  1313. package/src/permissions/trust-client.ts +0 -359
  1314. package/src/permissions/trust-store-interface.ts +0 -100
  1315. package/src/permissions/trust-store.ts +0 -1330
  1316. package/src/permissions/v2-consent-policy.ts +0 -87
  1317. package/src/permissions/web-risk-classifier.test.ts +0 -170
  1318. package/src/permissions/web-risk-classifier.ts +0 -89
  1319. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +0 -715
  1320. package/src/runtime/__tests__/capability-tokens.test.ts +0 -258
  1321. package/src/runtime/actor-refresh-token-store.ts +0 -156
  1322. package/src/runtime/actor-token-store.ts +0 -207
  1323. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -264
  1324. package/src/runtime/auth/credential-service.ts +0 -352
  1325. package/src/runtime/conversation-approval-overrides.ts +0 -86
  1326. package/src/runtime/routes/browser-extension-pair-routes.ts +0 -575
  1327. package/src/runtime/routes/channel-routes.ts +0 -112
  1328. package/src/runtime/routes/contact-routes.test.ts +0 -298
  1329. package/src/runtime/routes/guardian-bootstrap-routes.ts +0 -175
  1330. package/src/runtime/routes/guardian-refresh-routes.ts +0 -79
  1331. package/src/runtime/routes/invite-routes.ts +0 -280
  1332. package/src/runtime/routes/pairing-routes.ts +0 -431
  1333. package/src/runtime/routes/playground/deps.ts +0 -56
  1334. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +0 -67
  1335. package/src/runtime/services/analyze-deps-singleton.ts +0 -32
  1336. package/src/tasks/ephemeral-permissions.ts +0 -55
  1337. package/src/tools/terminal/parser.ts +0 -623
  1338. package/src/types/qrcode.d.ts +0 -13
  1339. package/src/util/network-info.ts +0 -55
  1340. /package/node_modules/@vellumai/{ces-contracts → ces-client}/tsconfig.json +0 -0
  1341. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/grants.test.ts +0 -0
  1342. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/error.ts +0 -0
  1343. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/grants.ts +0 -0
  1344. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/handles.ts +0 -0
  1345. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rendering.ts +0 -0
  1346. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rpc.ts +0 -0
@@ -6,78 +6,37 @@ import {
6
6
  getAcpSessionManager,
7
7
  setBroadcastToAllClients,
8
8
  } from "../acp/index.js";
9
- import { enrichMessageWithSourcePaths } from "../agent/attachments.js";
10
- import type { AgentEvent } from "../agent/loop.js";
11
- import {
12
- createAssistantMessage,
13
- createUserMessage,
14
- } from "../agent/message-types.js";
15
9
  import { compileApp } from "../bundler/app-compiler.js";
16
- import {
17
- type ChannelId,
18
- type InterfaceId,
19
- parseChannelId,
20
- parseInterfaceId,
21
- supportsHostProxy,
22
- } from "../channels/types.js";
10
+ import { supportsHostProxy } from "../channels/types.js";
23
11
  import { getConfig } from "../config/loader.js";
24
12
  import { onContactChange } from "../contacts/contact-events.js";
25
13
  import type { CesClient } from "../credential-execution/client.js";
26
14
  import type { CesProcessManager } from "../credential-execution/process-manager.js";
27
- import type { FilingService } from "../filing/filing-service.js";
28
- import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
29
- import { CliIpcServer } from "../ipc/cli-server.js";
30
- import { registerBrowserIpcContextResolver } from "../ipc/routes/browser-context.js";
15
+ import { AssistantIpcServer } from "../ipc/assistant-server.js";
16
+ import { SkillIpcServer } from "../ipc/skill-server.js";
31
17
  import { getApp, getAppDirPath, isMultifileApp } from "../memory/app-store.js";
32
- import * as attachmentsStore from "../memory/attachments-store.js";
33
- import {
34
- createCanonicalGuardianRequest,
35
- generateCanonicalRequestCode,
36
- } from "../memory/canonical-guardian-store.js";
37
18
  import {
38
- addMessage,
39
- getConversation,
40
- getConversationMemoryScopeId,
41
- getConversationType,
42
- provenanceFromTrustContext,
43
- setConversationOriginChannelIfUnset,
44
- setConversationOriginInterfaceIfUnset,
45
- } from "../memory/conversation-crud.js";
46
- import {
47
- syncMessageToDisk,
48
- updateMetaFile,
49
- } from "../memory/conversation-disk-view.js";
19
+ uploadFileBackedAttachment,
20
+ validateAttachmentUpload,
21
+ } from "../memory/attachments-store.js";
50
22
  import { getOrCreateConversation } from "../memory/conversation-key-store.js";
51
23
  import { syncIdentityNameToPlatform } from "../platform/sync-identity.js";
52
- import { buildSystemPrompt } from "../prompts/system-prompt.js";
53
- import { CallSiteRoutingProvider } from "../providers/call-site-routing.js";
54
- import { RateLimitProvider } from "../providers/ratelimit.js";
55
- import { getProvider, initializeProviders } from "../providers/registry.js";
56
- import {
57
- registerDefaultWakeResolver,
58
- type WakeTarget,
59
- } from "../runtime/agent-wake.js";
24
+ import { initializeProviders } from "../providers/registry.js";
60
25
  import { buildAssistantEvent } from "../runtime/assistant-event.js";
61
26
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
62
27
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
63
28
  import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
64
- import { bridgeConfirmationRequestToGuardian } from "../runtime/confirmation-request-guardian-bridge.js";
65
- import { registerInteractiveUiResolver } from "../runtime/interactive-ui.js";
66
- import * as pendingInteractions from "../runtime/pending-interactions.js";
67
29
  import { checkIngressForSecrets } from "../security/secret-ingress.js";
68
- import { redactSecrets } from "../security/secret-scanner.js";
69
30
  import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
70
31
  import { registerCancelCallback } from "../signals/cancel.js";
71
32
  import { registerConversationUndoCallback } from "../signals/conversation-undo.js";
72
33
  import { appendEventToStream } from "../signals/event-stream.js";
73
34
  import { registerUserMessageCallback } from "../signals/user-message.js";
74
35
  import { getSubagentManager } from "../subagent/index.js";
75
- import { summarizeToolInput } from "../tools/tool-input-summary.js";
76
36
  import { createAbortReason } from "../util/abort-reasons.js";
77
37
  import { getLogger } from "../util/logger.js";
78
38
  import {
79
39
  getAvatarImagePath,
80
- getSandboxWorkingDir,
81
40
  getWorkspacePromptPath,
82
41
  } from "../util/platform.js";
83
42
  import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
@@ -85,38 +44,40 @@ import {
85
44
  AppSourceWatcher,
86
45
  setEnsureAppSourceWatcher,
87
46
  } from "./app-source-watcher.js";
88
- import { ConfigWatcher } from "./config-watcher.js";
89
- import {
90
- Conversation,
91
- type ConversationMemoryPolicy,
92
- DEFAULT_MEMORY_POLICY,
93
- } from "./conversation.js";
47
+ import { getConfigWatcher } from "./config-watcher.js";
48
+ import { Conversation } from "./conversation.js";
94
49
  import { ConversationEvictor } from "./conversation-evictor.js";
95
50
  import { registerLaunchConversationDeps } from "./conversation-launch.js";
96
- import { buildSlackMetaForPersistence } from "./conversation-messaging.js";
97
- import { formatCompactResult } from "./conversation-process.js";
98
- import { resolveChannelCapabilities } from "./conversation-runtime-assembly.js";
99
- import { resolveSlash, type SlashContext } from "./conversation-slash.js";
100
51
  import {
101
- refreshSurfacesForApp,
102
- showStandaloneSurface,
103
- } from "./conversation-surfaces.js";
52
+ allConversations,
53
+ clearAllActiveConversations,
54
+ clearConversations,
55
+ conversationEntries,
56
+ deleteConversation,
57
+ findConversation,
58
+ getConversationMap,
59
+ getOrCreateConversation as getOrCreateActiveConversation,
60
+ initConversationLifecycle,
61
+ setCesClientPromise,
62
+ } from "./conversation-store.js";
63
+ import { refreshSurfacesForApp } from "./conversation-surfaces.js";
104
64
  import { undoLastMessage } from "./handlers/conversations.js";
105
65
  import { parseIdentityFields } from "./handlers/identity.js";
106
- import type {
107
- ConversationCreateOptions,
108
- HandlerContext,
66
+ import {
67
+ type ConversationCreateOptions,
68
+ type HandlerContext,
109
69
  } from "./handlers/shared.js";
110
- import type { SkillOperationContext } from "./handlers/skills.js";
111
- import { HostBashProxy } from "./host-bash-proxy.js";
112
- import { HostBrowserProxy } from "./host-browser-proxy.js";
113
- import { HostCuProxy } from "./host-cu-proxy.js";
114
- import { HostFileProxy } from "./host-file-proxy.js";
70
+ import { setGlobalSkillIpcSender } from "./meet-host-supervisor.js";
115
71
  import type {
116
72
  ServerMessage,
117
73
  UserMessageAttachment,
118
74
  } from "./message-protocol.js";
119
- import { buildTransportHints } from "./transport-hints.js";
75
+ import {
76
+ makePendingInteractionRegistrar,
77
+ prepareConversationForMessage,
78
+ resolveTurnChannel,
79
+ resolveTurnInterface,
80
+ } from "./process-message.js";
120
81
 
121
82
  const log = getLogger("server");
122
83
 
@@ -134,181 +95,17 @@ function readPackageVersion(): string | undefined {
134
95
 
135
96
  const daemonVersion = readPackageVersion();
136
97
 
137
- function resolveTurnChannel(
138
- sourceChannel?: string,
139
- transportChannelId?: string,
140
- ): ChannelId {
141
- if (sourceChannel != null) {
142
- const parsed = parseChannelId(sourceChannel);
143
- if (!parsed) {
144
- throw new Error(`Invalid sourceChannel: ${sourceChannel}`);
145
- }
146
- return parsed;
147
- }
148
- if (transportChannelId != null) {
149
- const parsed = parseChannelId(transportChannelId);
150
- if (!parsed) {
151
- throw new Error(`Invalid transport.channelId: ${transportChannelId}`);
152
- }
153
- return parsed;
154
- }
155
- return "vellum";
156
- }
157
-
158
- function resolveTurnInterface(sourceInterface?: string): InterfaceId {
159
- if (sourceInterface != null) {
160
- const parsed = parseInterfaceId(sourceInterface);
161
- if (!parsed) {
162
- throw new Error(`Invalid sourceInterface: ${sourceInterface}`);
163
- }
164
- return parsed;
165
- }
166
- // Interface and channel are orthogonal dimensions; default explicitly
167
- // instead of deriving interface from channel.
168
- return "vellum";
169
- }
170
-
171
- function resolveCanonicalRequestSourceType(
172
- sourceChannel: string | undefined,
173
- ): "desktop" | "channel" | "voice" {
174
- if (sourceChannel === "phone") {
175
- return "voice";
176
- }
177
- if (sourceChannel === "vellum") {
178
- return "desktop";
179
- }
180
- return "channel";
181
- }
182
-
183
- /**
184
- * Build an onEvent callback that registers pending interactions when the agent
185
- * loop emits confirmation_request, secret_request, host_bash_request,
186
- * host_browser_request, host_file_request, or host_cu_request events. This
187
- * ensures that channel approval interception can look up the conversation by
188
- * requestId.
189
- */
190
- function makePendingInteractionRegistrar(
191
- conversation: Conversation,
192
- conversationId: string,
193
- ): (msg: ServerMessage) => void {
194
- return (msg: ServerMessage) => {
195
- if (msg.type === "confirmation_request") {
196
- pendingInteractions.register(msg.requestId, {
197
- conversation,
198
- conversationId,
199
- kind: "confirmation",
200
- confirmationDetails: {
201
- toolName: msg.toolName,
202
- input: msg.input,
203
- riskLevel: msg.riskLevel,
204
- executionTarget: msg.executionTarget,
205
- allowlistOptions: msg.allowlistOptions,
206
- scopeOptions: msg.scopeOptions,
207
- persistentDecisionsAllowed: msg.persistentDecisionsAllowed,
208
- temporaryOptionsAvailable: msg.temporaryOptionsAvailable,
209
- },
210
- });
211
-
212
- // Create a canonical guardian request so HTTP handlers can find it
213
- // via applyCanonicalGuardianDecision.
214
- try {
215
- const trustContext = conversation.trustContext;
216
- const sourceChannel = trustContext?.sourceChannel ?? "vellum";
217
- const inputRecord = msg.input as Record<string, unknown>;
218
- const activityRaw =
219
- (typeof inputRecord.activity === "string"
220
- ? inputRecord.activity
221
- : undefined) ??
222
- (typeof inputRecord.reason === "string"
223
- ? inputRecord.reason
224
- : undefined);
225
- const canonicalRequest = createCanonicalGuardianRequest({
226
- id: msg.requestId,
227
- kind: "tool_approval",
228
- sourceType: resolveCanonicalRequestSourceType(sourceChannel),
229
- sourceChannel,
230
- conversationId,
231
- requesterExternalUserId: trustContext?.requesterExternalUserId,
232
- requesterChatId: trustContext?.requesterChatId,
233
- guardianExternalUserId: trustContext?.guardianExternalUserId,
234
- guardianPrincipalId: trustContext?.guardianPrincipalId ?? undefined,
235
- toolName: msg.toolName,
236
- commandPreview:
237
- redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
238
- undefined,
239
- riskLevel: msg.riskLevel,
240
- activityText: activityRaw ? redactSecrets(activityRaw) : undefined,
241
- executionTarget: msg.executionTarget,
242
- status: "pending",
243
- requestCode: generateCanonicalRequestCode(),
244
- expiresAt: Date.now() + 5 * 60 * 1000,
245
- });
246
-
247
- // For trusted-contact sessions, bridge to guardian.question so the
248
- // guardian gets notified and can approve via callback/request-code.
249
- if (trustContext) {
250
- bridgeConfirmationRequestToGuardian({
251
- canonicalRequest,
252
- trustContext,
253
- conversationId,
254
- toolName: msg.toolName,
255
- assistantId:
256
- conversation.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
257
- });
258
- }
259
- } catch (err) {
260
- log.debug(
261
- { err, requestId: msg.requestId, conversationId },
262
- "Failed to create canonical request from pending interaction registrar",
263
- );
264
- }
265
- } else if (msg.type === "secret_request") {
266
- pendingInteractions.register(msg.requestId, {
267
- conversation,
268
- conversationId,
269
- kind: "secret",
270
- });
271
- } else if (msg.type === "host_bash_request") {
272
- pendingInteractions.register(msg.requestId, {
273
- conversation,
274
- conversationId,
275
- kind: "host_bash",
276
- });
277
- } else if (msg.type === "host_browser_request") {
278
- pendingInteractions.register(msg.requestId, {
279
- conversation,
280
- conversationId,
281
- kind: "host_browser",
282
- });
283
- } else if (msg.type === "host_file_request") {
284
- pendingInteractions.register(msg.requestId, {
285
- conversation,
286
- conversationId,
287
- kind: "host_file",
288
- });
289
- } else if (msg.type === "host_cu_request") {
290
- pendingInteractions.register(msg.requestId, {
291
- conversation,
292
- conversationId,
293
- kind: "host_cu",
294
- });
295
- }
296
- };
297
- }
298
-
299
98
  export class DaemonServer {
300
- private conversations = new Map<string, Conversation>();
301
- private conversationOptions = new Map<string, ConversationCreateOptions>();
302
- private conversationCreating = new Map<string, Promise<Conversation>>();
303
99
  private sharedRequestTimestamps: number[] = [];
304
100
  private unsubscribeContactChange: (() => void) | null = null;
305
101
  private evictor: ConversationEvictor;
306
102
  private _hubChain: Promise<void> = Promise.resolve();
307
103
 
308
104
  // Composed subsystems
309
- private configWatcher = new ConfigWatcher();
105
+ private configWatcher = getConfigWatcher();
310
106
  private appSourceWatcher = new AppSourceWatcher();
311
- private cliIpc = new CliIpcServer();
107
+ private cliIpc = new AssistantIpcServer();
108
+ private skillIpc = new SkillIpcServer();
312
109
 
313
110
  // CES (Credential Execution Service) — process-level singleton.
314
111
  // Lifecycle is managed by startCesProcess() in lifecycle.ts; the server
@@ -352,6 +149,7 @@ export class DaemonServer {
352
149
  }
353
150
  return client;
354
151
  });
152
+ setCesClientPromise(this.cesClientPromise);
355
153
  }
356
154
  }
357
155
 
@@ -374,68 +172,22 @@ export class DaemonServer {
374
172
  this.cesClientRef = client;
375
173
  }
376
174
 
377
- /** Optional heartbeat service reference for "Run Now" from the UI. */
378
- private _heartbeatService?: HeartbeatService;
379
-
380
- setHeartbeatService(service: HeartbeatService): void {
381
- this._heartbeatService = service;
382
- }
383
-
384
- getHeartbeatService(): HeartbeatService | undefined {
385
- return this._heartbeatService;
386
- }
387
-
388
- /** Optional filing service reference for "Run Now" from the UI. */
389
- private _filingService?: FilingService;
390
-
391
- setFilingService(service: FilingService): void {
392
- this._filingService = service;
393
- }
394
-
395
- getFilingService(): FilingService | undefined {
396
- return this._filingService;
397
- }
398
-
399
- private deriveMemoryPolicy(conversationId: string): ConversationMemoryPolicy {
400
- const conversationType = getConversationType(conversationId);
401
- if (conversationType === "private") {
402
- return {
403
- scopeId: getConversationMemoryScopeId(conversationId),
404
- includeDefaultFallback: true,
405
- strictSideEffects: true,
406
- };
407
- }
408
- return DEFAULT_MEMORY_POLICY;
409
- }
410
-
411
- private applyTransportMetadata(
412
- conversation: Conversation,
413
- options: ConversationCreateOptions | undefined,
414
- ): void {
415
- const transport = options?.transport;
416
- if (!transport) return;
417
- log.debug(
418
- { channelId: transport.channelId },
419
- "Transport metadata received",
420
- );
421
- conversation.setTransportHints(buildTransportHints(transport));
422
- // Route client-reported host env through the capability-gated setter on
423
- // Conversation so both the create/reuse path here and the queue-drain
424
- // path in conversation-process share one implementation. The method
425
- // gates on `supportsHostProxy` (not a specific interface name), so any
426
- // new host-capable client added to `HostProxyInterfaceId` will flow its
427
- // host env through automatically.
428
- conversation.applyHostEnvFromTransport(transport);
429
- }
430
-
431
175
  constructor() {
432
- this.evictor = new ConversationEvictor(this.conversations);
176
+ this.evictor = new ConversationEvictor(getConversationMap());
433
177
  getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
434
178
  getSubagentManager().broadcastToAllClients = (msg) => this.broadcast(msg);
435
- getSubagentManager().resolveParentConversation = (id) =>
436
- this.conversations.get(id);
179
+ initConversationLifecycle({
180
+ evictor: this.evictor,
181
+ sharedRequestTimestamps: this.sharedRequestTimestamps,
182
+ });
437
183
  setBroadcastToAllClients((msg) => this.broadcast(msg));
438
184
  setEnsureAppSourceWatcher(() => this.appSourceWatcher.ensureStarted());
185
+ // Wire the skill IPC server into the meet-host supervisor's lazy
186
+ // dispatch path. The supervisor is constructed in
187
+ // `initializeProvidersAndTools()` (via `startMeetHost`), which can run
188
+ // before or after this DaemonServer instance, so the sender flows
189
+ // through a module-level global rather than constructor injection.
190
+ setGlobalSkillIpcSender(this.skillIpc);
439
191
  this.evictor.onEvict = (conversationId: string) => {
440
192
  getSubagentManager().abortAllForParent(conversationId);
441
193
  };
@@ -451,7 +203,7 @@ export class DaemonServer {
451
203
  sendToClient,
452
204
  notification,
453
205
  ) => {
454
- const parentConversation = this.conversations.get(parentConversationId);
206
+ const parentConversation = findConversation(parentConversationId);
455
207
  if (!parentConversation) {
456
208
  log.warn(
457
209
  { parentConversationId },
@@ -492,7 +244,7 @@ export class DaemonServer {
492
244
  message,
493
245
  sendToClient,
494
246
  ) => {
495
- const parentConversation = this.conversations.get(parentConversationId);
247
+ const parentConversation = findConversation(parentConversationId);
496
248
  if (!parentConversation) {
497
249
  log.warn(
498
250
  { parentConversationId },
@@ -611,10 +363,6 @@ export class DaemonServer {
611
363
  this.broadcast({ type: "sounds_config_updated" });
612
364
  }
613
365
 
614
- private broadcastFeatureFlagsChanged(): void {
615
- this.broadcast({ type: "feature_flags_changed" });
616
- }
617
-
618
366
  private broadcastAvatarUpdated(): void {
619
367
  this.broadcast({
620
368
  type: "avatar_updated",
@@ -631,7 +379,7 @@ export class DaemonServer {
631
379
  if (!app) return;
632
380
 
633
381
  const doRefresh = () => {
634
- for (const conversation of this.conversations.values()) {
382
+ for (const conversation of allConversations()) {
635
383
  refreshSurfacesForApp(conversation, appId, { fileChange: true });
636
384
  }
637
385
  this.broadcast({ type: "app_files_changed", appId });
@@ -671,12 +419,12 @@ export class DaemonServer {
671
419
 
672
420
  registerDaemonCallbacks({
673
421
  getOrCreateConversation: (conversationId) =>
674
- this.getOrCreateConversation(conversationId),
422
+ getOrCreateActiveConversation(conversationId),
675
423
  broadcast: (msg) => this.broadcast(msg),
676
424
  });
677
425
 
678
426
  registerCancelCallback((conversationId) => {
679
- const conversation = this.conversations.get(conversationId);
427
+ const conversation = findConversation(conversationId);
680
428
  if (!conversation) return false;
681
429
  this.evictor.touch(conversationId);
682
430
  conversation.abort(
@@ -691,7 +439,7 @@ export class DaemonServer {
691
439
  });
692
440
 
693
441
  registerConversationUndoCallback((conversationId) =>
694
- undoLastMessage(conversationId, this.handlerContext()),
442
+ undoLastMessage(conversationId),
695
443
  );
696
444
 
697
445
  registerUserMessageCallback(async (params) => {
@@ -710,7 +458,7 @@ export class DaemonServer {
710
458
  const { conversationId } = getOrCreateConversation(
711
459
  params.conversationKey,
712
460
  );
713
- const conversation = await this.getOrCreateConversation(conversationId);
461
+ const conversation = await getOrCreateActiveConversation(conversationId);
714
462
 
715
463
  // Register file-backed attachments so they flow through the send
716
464
  // pipeline as images the LLM can see directly.
@@ -719,10 +467,7 @@ export class DaemonServer {
719
467
  if (params.attachments && params.attachments.length > 0) {
720
468
  for (const a of params.attachments) {
721
469
  try {
722
- const validation = attachmentsStore.validateAttachmentUpload(
723
- a.filename,
724
- a.mimeType,
725
- );
470
+ const validation = validateAttachmentUpload(a.filename, a.mimeType);
726
471
  if (!validation.ok) {
727
472
  log.warn(
728
473
  { error: validation.error, path: a.path },
@@ -731,7 +476,7 @@ export class DaemonServer {
731
476
  continue;
732
477
  }
733
478
  const size = statSync(a.path).size;
734
- const stored = attachmentsStore.uploadFileBackedAttachment(
479
+ const stored = uploadFileBackedAttachment(
735
480
  a.filename,
736
481
  a.mimeType,
737
482
  a.path,
@@ -812,94 +557,19 @@ export class DaemonServer {
812
557
  return { accepted: true };
813
558
  });
814
559
 
815
- // Install the default resolver for `wakeAgentForOpportunity()` so
816
- // internal subsystems (e.g. the Meet chat-opportunity detector wired
817
- // up in `MeetSessionManager`) can invoke it without having to build
818
- // a `WakeTarget` adapter themselves. The adapter wraps a live
819
- // `Conversation` fetched from the in-memory map / hydrated from the
820
- // DB, exposing only the narrow surface the wake helper needs.
821
- registerDefaultWakeResolver(async (conversationId) => {
822
- try {
823
- // Only resolve existing conversations — don't create ghost
824
- // conversations for stale targets (e.g. meetings that ended
825
- // but a delayed opportunity callback still fires).
826
- const existing = getConversation(conversationId);
827
- if (!existing) return null;
828
- const conversation = await this.getOrCreateConversation(conversationId);
829
- return conversationToWakeTarget(conversation);
830
- } catch (err) {
831
- log.warn(
832
- { err, conversationId },
833
- "agent-wake default resolver: failed to hydrate conversation",
834
- );
835
- return null;
836
- }
837
- });
838
-
839
- // Install the interactive UI resolver so skills and IPC handlers can
840
- // present ad-hoc UI surfaces (confirmations, forms) to the user via
841
- // `requestInteractiveUi()`. Interactive UI requires a client to be
842
- // actively connected to the conversation (via SSE), which means the
843
- // conversation must be in the in-memory map. If the conversation was
844
- // evicted from memory the client is definitely disconnected, so
845
- // hydration from persistent storage is pointless — the hydrated
846
- // conversation would have hasNoClient=true, causing
847
- // canShowInteractiveUi() to return false and the surface to be
848
- // cancelled with no_interactive_surface. We skip that wasted work
849
- // and return conversation_not_found directly.
850
- registerInteractiveUiResolver(async (request) => {
851
- const conversation = this.conversations.get(request.conversationId);
852
-
853
- if (!conversation) {
854
- log.warn(
855
- {
856
- conversationId: request.conversationId,
857
- surfaceType: request.surfaceType,
858
- },
859
- "interactive-ui resolver: conversation not in memory (client not connected); failing closed",
860
- );
861
- return {
862
- status: "cancelled" as const,
863
- surfaceId: `ui-resolver-${Date.now()}`,
864
- cancellationReason: "conversation_not_found" as const,
865
- };
866
- }
560
+ await this.cliIpc.start();
867
561
 
868
- // Generate a unique surface ID and delegate to the conversation's
869
- // standalone surface lifecycle. The returned Promise blocks until
870
- // the user submits, cancels, or the timeout elapses.
871
- const surfaceId = `ui-standalone-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
872
- return showStandaloneSurface(conversation, request, surfaceId);
873
- });
874
-
875
- // Allow `browser_execute` IPC calls to reuse live conversation browser
876
- // proxy wiring (when a caller passes a conversationId from
877
- // __CONVERSATION_ID / __SKILL_CONTEXT_JSON). This keeps nested
878
- // `assistant browser status` checks consistent with the parent turn's
879
- // extension connectivity instead of always falling back to a synthetic
880
- // browser-cli session that has no hostBrowserProxy.
881
- registerBrowserIpcContextResolver((conversationId) => {
882
- const conversation = this.conversations.get(conversationId);
883
- if (!conversation) return null;
884
- return {
885
- conversationId,
886
- trustClass: conversation.trustContext?.trustClass ?? "guardian",
887
- hostBrowserProxy: conversation.hostBrowserProxy,
888
- transportInterface: conversation.transportInterface,
889
- hostBrowserRegistryRouted: !!conversation.hostBrowserSenderOverride,
890
- };
891
- });
892
-
893
- // Start the CLI IPC server. Built-in methods (wake_conversation) are
894
- // registered by the constructor; CLI commands connect to this socket to
895
- // invoke daemon-side operations that require in-process state.
896
- this.cliIpc.start();
562
+ // Start the skill IPC server. First-party skill processes connect to this
563
+ // socket to access host capabilities (host.log, host.config.*,
564
+ // host.events.*, host.registries.*). Route registry is populated by
565
+ // subsequent PRs in the skill-isolation plan.
566
+ await this.skillIpc.start();
897
567
 
898
568
  // Wire the launchConversation helper to daemon-side state so
899
569
  // handleSurfaceAction can spawn conversations through it.
900
570
  registerLaunchConversationDeps({
901
571
  getOrCreateConversation: (id, options) =>
902
- this.getOrCreateConversation(id, options),
572
+ getOrCreateActiveConversation(id, options),
903
573
  persistAndProcessMessage: (
904
574
  conversationId,
905
575
  content,
@@ -927,7 +597,6 @@ export class DaemonServer {
927
597
  () => this.broadcastSoundsConfigUpdated(),
928
598
  () => this.broadcastAvatarUpdated(),
929
599
  () => this.broadcastConfigChanged(),
930
- () => this.broadcastFeatureFlagsChanged(),
931
600
  );
932
601
 
933
602
  this.syncIdentityToPlatform();
@@ -949,15 +618,16 @@ export class DaemonServer {
949
618
  this.configWatcher.stop();
950
619
  this.appSourceWatcher.stop();
951
620
  this.cliIpc.stop();
621
+ this.skillIpc.stop();
952
622
  if (this.unsubscribeContactChange) {
953
623
  this.unsubscribeContactChange();
954
624
  this.unsubscribeContactChange = null;
955
625
  }
956
626
 
957
- for (const conversation of this.conversations.values()) {
627
+ for (const conversation of allConversations()) {
958
628
  conversation.dispose();
959
629
  }
960
- this.conversations.clear();
630
+ clearConversations();
961
631
 
962
632
  // Abort any in-flight CES initialization so it fails fast instead of
963
633
  // blocking shutdown for up to ~15s (socket connect + handshake timeouts).
@@ -982,6 +652,7 @@ export class DaemonServer {
982
652
  if (this.cesClientPromise) {
983
653
  await this.cesClientPromise.catch(() => undefined);
984
654
  this.cesClientPromise = undefined;
655
+ setCesClientPromise(undefined);
985
656
  }
986
657
  if (this.cesProcessManager) {
987
658
  this.cesProcessManager = undefined;
@@ -1000,42 +671,13 @@ export class DaemonServer {
1000
671
  });
1001
672
  }
1002
673
 
1003
- clearAllConversations(): number {
1004
- const count = this.conversations.size;
1005
- const subagentManager = getSubagentManager();
1006
- for (const id of this.conversations.keys()) {
1007
- this.evictor.remove(id);
1008
- subagentManager.abortAllForParent(id);
1009
- }
1010
- for (const conversation of this.conversations.values()) {
1011
- conversation.dispose();
1012
- }
1013
- this.conversations.clear();
1014
- this.conversationOptions.clear();
1015
- return count;
1016
- }
1017
-
1018
- /**
1019
- * Abort and dispose a single in-memory conversation, removing it from the
1020
- * conversation map. No-op if no conversation exists for the given ID.
1021
- */
1022
- destroyConversation(conversationId: string): void {
1023
- const conversation = this.conversations.get(conversationId);
1024
- if (!conversation) return;
1025
- this.evictor.remove(conversationId);
1026
- getSubagentManager().abortAllForParent(conversationId);
1027
- conversation.dispose();
1028
- this.conversations.delete(conversationId);
1029
- this.conversationOptions.delete(conversationId);
1030
- }
1031
-
1032
674
  private evictConversationsForReload(): void {
1033
675
  const subagentManager = getSubagentManager();
1034
- for (const [id, conversation] of this.conversations) {
676
+ for (const [id, conversation] of conversationEntries()) {
1035
677
  if (!conversation.isProcessing()) {
1036
678
  subagentManager.abortAllForParent(id);
1037
679
  conversation.dispose();
1038
- this.conversations.delete(id);
680
+ deleteConversation(id);
1039
681
  this.evictor.remove(id);
1040
682
  } else {
1041
683
  conversation.markStale();
@@ -1065,144 +707,10 @@ export class DaemonServer {
1065
707
  this.evictConversationsForReload();
1066
708
  }
1067
709
 
1068
- private async getOrCreateConversation(
1069
- conversationId: string,
1070
- options?: ConversationCreateOptions,
1071
- ): Promise<Conversation> {
1072
- let conversation = this.conversations.get(conversationId);
1073
- const sendToClient = () => {};
1074
-
1075
- const { taskRunId: _taskRunId, ...persistentOptions } = options ?? {};
1076
- if (Object.values(persistentOptions).some((v) => v !== undefined)) {
1077
- this.conversationOptions.set(conversationId, {
1078
- ...this.conversationOptions.get(conversationId),
1079
- ...persistentOptions,
1080
- });
1081
- }
1082
-
1083
- if (
1084
- !conversation ||
1085
- (conversation.isStale() && !conversation.isProcessing())
1086
- ) {
1087
- if (conversation) {
1088
- getSubagentManager().abortAllForParent(conversationId);
1089
- conversation.dispose();
1090
- }
1091
-
1092
- const pending = this.conversationCreating.get(conversationId);
1093
- if (pending) {
1094
- conversation = await pending;
1095
- return conversation;
1096
- }
1097
-
1098
- const storedOptions = this.conversationOptions.get(conversationId);
1099
-
1100
- const createPromise = (async () => {
1101
- const config = getConfig();
1102
- let provider = getProvider(config.llm.default.provider);
1103
- // Per-call `options.config.callSite` can resolve to a provider name
1104
- // that differs from `llm.default.provider`. Wrap the default
1105
- // provider so the actual transport routes correctly per call,
1106
- // rather than only forwarding metadata to the default's HTTP
1107
- // client. See `providers/call-site-routing.ts`.
1108
- provider = new CallSiteRoutingProvider(provider, (name) => {
1109
- try {
1110
- return getProvider(name);
1111
- } catch {
1112
- return undefined;
1113
- }
1114
- });
1115
- const { rateLimit } = config;
1116
- if (rateLimit.maxRequestsPerMinute > 0) {
1117
- provider = new RateLimitProvider(
1118
- provider,
1119
- rateLimit,
1120
- this.sharedRequestTimestamps,
1121
- );
1122
- }
1123
- const workingDir = getSandboxWorkingDir();
1124
-
1125
- const systemPrompt =
1126
- storedOptions?.systemPromptOverride ?? buildSystemPrompt();
1127
- const maxTokens =
1128
- storedOptions?.maxResponseTokens ?? config.llm.default.maxTokens;
1129
-
1130
- const memoryPolicy = this.deriveMemoryPolicy(conversationId);
1131
- // Resolve the shared CES client (may still be initializing).
1132
- const sharedCesClient = this.cesClientPromise
1133
- ? await this.cesClientPromise
1134
- : undefined;
1135
- const newConversation = new Conversation(
1136
- conversationId,
1137
- provider,
1138
- systemPrompt,
1139
- maxTokens,
1140
- sendToClient,
1141
- workingDir,
1142
- (msg) => this.broadcast(msg),
1143
- memoryPolicy,
1144
- sharedCesClient,
1145
- storedOptions?.speed,
1146
- undefined,
1147
- storedOptions?.modelOverride,
1148
- );
1149
- newConversation.updateClient(sendToClient, true);
1150
- await newConversation.loadFromDb();
1151
- // Restore trust/auth context and assistant ID from stored options so
1152
- // that evicted sessions rehydrated by undo/regenerate don't run with
1153
- // unscoped history. Without this, an untrusted actor could operate
1154
- // on the full conversation after eviction.
1155
- if (storedOptions?.assistantId) {
1156
- newConversation.setAssistantId(storedOptions.assistantId);
1157
- }
1158
- if (storedOptions?.trustContext) {
1159
- newConversation.setTrustContext(storedOptions.trustContext);
1160
- }
1161
- if (storedOptions?.authContext) {
1162
- newConversation.setAuthContext(storedOptions.authContext);
1163
- }
1164
- if (storedOptions?.trustContext || storedOptions?.authContext) {
1165
- await newConversation.ensureActorScopedHistory();
1166
- }
1167
- this.applyTransportMetadata(newConversation, storedOptions);
1168
- this.conversations.set(conversationId, newConversation);
1169
- return newConversation;
1170
- })();
1171
-
1172
- this.conversationCreating.set(conversationId, createPromise);
1173
- try {
1174
- conversation = await createPromise;
1175
- } finally {
1176
- this.conversationCreating.delete(conversationId);
1177
- }
1178
- this.evictor.touch(conversationId);
1179
- } else {
1180
- // Only apply transport metadata when the conversation is idle.
1181
- // When processing, the hints are stored on the queued message and
1182
- // will be applied at dequeue time — applying them here would
1183
- // overwrite the in-flight conversation's transportHints.
1184
- if (!conversation.isProcessing()) {
1185
- this.applyTransportMetadata(conversation, options);
1186
- // trustContext is reapplied here only when the conversation is idle,
1187
- // so concurrent requests cannot overwrite an in-flight turn's guardian
1188
- // scope. Direct callers (e.g. schedule-routes run-now) that invoke
1189
- // processMessage without going through prepareConversationForMessage
1190
- // rely on this to pick up the trustContext passed in options.
1191
- // prepareConversationForMessage also reapplies after its own idle check.
1192
- if (options?.trustContext !== undefined) {
1193
- conversation.setTrustContext(options.trustContext);
1194
- }
1195
- }
1196
- this.evictor.touch(conversationId);
1197
- }
1198
- return conversation;
1199
- }
1200
-
1201
710
  // ── Handler context ────────────────────────────────────────────────
1202
711
 
1203
712
  private handlerContext(): HandlerContext {
1204
713
  return {
1205
- conversations: this.conversations,
1206
714
  sharedRequestTimestamps: this.sharedRequestTimestamps,
1207
715
  debounceTimers: this.configWatcher.timers,
1208
716
  suppressConfigReload: this.configWatcher.suppressConfigReload,
@@ -1214,199 +722,15 @@ export class DaemonServer {
1214
722
  },
1215
723
  send: (msg) => this.broadcast(msg),
1216
724
  broadcast: (msg) => this.broadcast(msg),
1217
- clearAllConversations: () => this.clearAllConversations(),
725
+ clearAllConversations: () => clearAllActiveConversations(),
1218
726
  getOrCreateConversation: (id, options?) =>
1219
- this.getOrCreateConversation(id, options),
727
+ getOrCreateActiveConversation(id, options),
1220
728
  touchConversation: (id) => this.evictor.touch(id),
1221
- heartbeatService: this._heartbeatService,
1222
- };
1223
- }
1224
-
1225
- /** Public subset of handler context for skill management HTTP routes. */
1226
- getSkillContext(): SkillOperationContext {
1227
- return {
1228
- debounceTimers: this.configWatcher.timers,
1229
- setSuppressConfigReload: (value: boolean) => {
1230
- this.configWatcher.suppressConfigReload = value;
1231
- },
1232
- updateConfigFingerprint: () => {
1233
- this.configWatcher.updateFingerprint();
1234
- },
1235
- broadcast: (msg) => this.broadcast(msg),
1236
729
  };
1237
730
  }
1238
731
 
1239
732
  // ── HTTP message processing ─────────────────────────────────────────
1240
733
 
1241
- private async prepareConversationForMessage(
1242
- conversationId: string,
1243
- content: string,
1244
- attachmentIds: string[] | undefined,
1245
- options: ConversationCreateOptions | undefined,
1246
- sourceChannel: string | undefined,
1247
- sourceInterface: string | undefined,
1248
- ): Promise<{
1249
- conversation: Conversation;
1250
- attachments: {
1251
- id: string;
1252
- filename: string;
1253
- mimeType: string;
1254
- data: string;
1255
- filePath?: string;
1256
- }[];
1257
- }> {
1258
- const conversation = await this.getOrCreateConversation(
1259
- conversationId,
1260
- options,
1261
- );
1262
-
1263
- if (conversation.isProcessing()) {
1264
- throw new Error("Conversation is already processing a message");
1265
- }
1266
-
1267
- const resolvedChannel = resolveTurnChannel(
1268
- sourceChannel,
1269
- options?.transport?.channelId,
1270
- );
1271
- const resolvedInterface = resolveTurnInterface(sourceInterface);
1272
- conversation.setAssistantId(
1273
- options?.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
1274
- );
1275
- conversation.taskRunId = options?.taskRunId;
1276
- // Only overwrite trust/auth context when explicitly provided. Callers that
1277
- // don't supply a trust context (e.g. signal-injected messages) should
1278
- // inherit whatever the conversation already has from a prior session.
1279
- if (options?.trustContext !== undefined) {
1280
- conversation.setTrustContext(options.trustContext);
1281
- }
1282
- if (options?.authContext !== undefined) {
1283
- conversation.setAuthContext(options.authContext);
1284
- }
1285
- await conversation.ensureActorScopedHistory();
1286
-
1287
- // Persist the conversation's current trust/auth context so it survives
1288
- // eviction and recreation. The restore path in getOrCreateConversation
1289
- // reads from storedOptions.trustContext / storedOptions.authContext.
1290
- // Always write — including null — so explicit clearing isn't lost.
1291
- this.conversationOptions.set(conversationId, {
1292
- ...this.conversationOptions.get(conversationId),
1293
- trustContext: conversation.trustContext,
1294
- authContext: conversation.authContext,
1295
- });
1296
- conversation.setChannelCapabilities(
1297
- resolveChannelCapabilities(
1298
- sourceChannel,
1299
- sourceInterface,
1300
- options?.transport?.chatType,
1301
- ),
1302
- );
1303
- // Chrome-extension host_browser wiring is intentionally not supported
1304
- // through this entry point. `prepareConversationForMessage` constructs
1305
- // host_browser proxies that capture `conversation.getCurrentSender()`
1306
- // directly, which routes browser frames through the daemon SSE channel.
1307
- // This is correct for macOS (SSE-based host proxy), but chrome-extension
1308
- // requires the `ChromeExtensionRegistry` WebSocket transport instead.
1309
- // Chrome-extension flows reach host_browser exclusively through the
1310
- // `/v1/messages` flow in `conversation-routes.ts`, which wires a
1311
- // registry-aware sender and sets `hostBrowserSenderOverride`.
1312
- //
1313
- // Fail loudly rather than silently returning a mis-wired proxy so that
1314
- // any future caller that tries to route chrome-extension through this
1315
- // path discovers the gap immediately. When the time comes, factor the
1316
- // wiring in conversation-routes.ts (registry lookup + override) into a
1317
- // shared helper and call it from both sites.
1318
- if (resolvedInterface === "chrome-extension") {
1319
- throw new Error(
1320
- "prepareConversationForMessage does not yet support chrome-extension transport — " +
1321
- "use the conversation-routes.ts /v1/messages flow which routes host_browser through " +
1322
- "the ChromeExtensionRegistry. If you need chrome-extension here, factor out the " +
1323
- "wiring in conversation-routes.ts into a shared helper.",
1324
- );
1325
- }
1326
- // Only create each host proxy for interfaces that support the matching
1327
- // capability. macOS supports all four; the chrome-extension interface only
1328
- // supports host_browser. Non-desktop conversations (CLI, channels, headless)
1329
- // fall back to local execution.
1330
- // Guard: don't replace an active proxy during concurrent turn races —
1331
- // another request may have started processing between the isProcessing()
1332
- // check above and the await on ensureActorScopedHistory().
1333
- if (supportsHostProxy(resolvedInterface, "host_bash")) {
1334
- if (!conversation.isProcessing() || !conversation.hostBashProxy) {
1335
- conversation.setHostBashProxy(
1336
- new HostBashProxy(conversation.getCurrentSender(), (requestId) => {
1337
- pendingInteractions.resolve(requestId);
1338
- }),
1339
- );
1340
- }
1341
- } else if (!conversation.isProcessing()) {
1342
- conversation.setHostBashProxy(undefined);
1343
- }
1344
- if (supportsHostProxy(resolvedInterface, "host_browser")) {
1345
- if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
1346
- conversation.setHostBrowserProxy(
1347
- new HostBrowserProxy(conversation.getCurrentSender(), (requestId) => {
1348
- pendingInteractions.resolve(requestId);
1349
- }),
1350
- );
1351
- }
1352
- } else if (!conversation.isProcessing()) {
1353
- conversation.setHostBrowserProxy(undefined);
1354
- }
1355
- if (supportsHostProxy(resolvedInterface, "host_file")) {
1356
- if (!conversation.isProcessing() || !conversation.hostFileProxy) {
1357
- conversation.setHostFileProxy(
1358
- new HostFileProxy(conversation.getCurrentSender(), (requestId) => {
1359
- pendingInteractions.resolve(requestId);
1360
- }),
1361
- );
1362
- }
1363
- } else if (!conversation.isProcessing()) {
1364
- conversation.setHostFileProxy(undefined);
1365
- }
1366
- if (supportsHostProxy(resolvedInterface, "host_cu")) {
1367
- if (!conversation.isProcessing() || !conversation.hostCuProxy) {
1368
- conversation.setHostCuProxy(
1369
- new HostCuProxy(conversation.getCurrentSender(), (requestId) => {
1370
- pendingInteractions.resolve(requestId);
1371
- }),
1372
- );
1373
- }
1374
- conversation.addPreactivatedSkillId("computer-use");
1375
- } else if (!conversation.isProcessing()) {
1376
- conversation.setHostCuProxy(undefined);
1377
- }
1378
- conversation.setCommandIntent(options?.commandIntent ?? null);
1379
- conversation.setTurnChannelContext({
1380
- userMessageChannel: resolvedChannel,
1381
- assistantMessageChannel: resolvedChannel,
1382
- });
1383
- conversation.setTurnInterfaceContext({
1384
- userMessageInterface: resolvedInterface,
1385
- assistantMessageInterface: resolvedInterface,
1386
- });
1387
-
1388
- const attachments = attachmentIds
1389
- ? (() => {
1390
- const resolved = attachmentsStore.getAttachmentsByIds(attachmentIds, {
1391
- hydrateFileData: true,
1392
- });
1393
- const sourcePaths =
1394
- attachmentsStore.getSourcePathsForAttachments(attachmentIds);
1395
- return resolved.map((a) => ({
1396
- id: a.id,
1397
- filename: a.originalFilename,
1398
- mimeType: a.mimeType,
1399
- data: a.dataBase64,
1400
- ...(sourcePaths.has(a.id)
1401
- ? { filePath: sourcePaths.get(a.id) }
1402
- : {}),
1403
- }));
1404
- })()
1405
- : [];
1406
-
1407
- return { conversation, attachments };
1408
- }
1409
-
1410
734
  async persistAndProcessMessage(
1411
735
  conversationId: string,
1412
736
  content: string,
@@ -1415,15 +739,14 @@ export class DaemonServer {
1415
739
  sourceChannel?: string,
1416
740
  sourceInterface?: string,
1417
741
  ): Promise<{ messageId: string }> {
1418
- const { conversation, attachments } =
1419
- await this.prepareConversationForMessage(
1420
- conversationId,
1421
- content,
1422
- attachmentIds,
1423
- options,
1424
- sourceChannel,
1425
- sourceInterface,
1426
- );
742
+ const { conversation, attachments } = await prepareConversationForMessage(
743
+ conversationId,
744
+ content,
745
+ attachmentIds,
746
+ options,
747
+ sourceChannel,
748
+ sourceInterface,
749
+ );
1427
750
 
1428
751
  const requestId = crypto.randomUUID();
1429
752
  const messageId = await conversation.persistUserMessage(
@@ -1493,259 +816,6 @@ export class DaemonServer {
1493
816
  return { messageId };
1494
817
  }
1495
818
 
1496
- async processMessage(
1497
- conversationId: string,
1498
- content: string,
1499
- attachmentIds?: string[],
1500
- options?: ConversationCreateOptions,
1501
- sourceChannel?: string,
1502
- sourceInterface?: string,
1503
- ): Promise<{ messageId: string }> {
1504
- const { conversation, attachments } =
1505
- await this.prepareConversationForMessage(
1506
- conversationId,
1507
- content,
1508
- attachmentIds,
1509
- options,
1510
- sourceChannel,
1511
- sourceInterface,
1512
- );
1513
-
1514
- const config = getConfig();
1515
- const serverInterfaceCtx = conversation.getTurnInterfaceContext();
1516
- const slashContext: SlashContext = {
1517
- messageCount: conversation.getMessages().length,
1518
- inputTokens: conversation.usageStats.inputTokens,
1519
- outputTokens: conversation.usageStats.outputTokens,
1520
- maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
1521
- model: config.llm.default.model,
1522
- provider: config.llm.default.provider,
1523
- estimatedCost: conversation.usageStats.estimatedCost,
1524
- userMessageInterface: serverInterfaceCtx?.userMessageInterface,
1525
- };
1526
- const slashResult = await resolveSlash(content, slashContext);
1527
-
1528
- // Slack inbound metadata is materialized once here for the slash-command
1529
- // bypass paths (unknown-slash and /compact), which persist the user row
1530
- // directly via `addMessage` and would otherwise drop the envelope. The
1531
- // agent-loop path does not consume this variable — it forwards
1532
- // `options.slackInbound` through `persistMetadata` and the envelope is
1533
- // built internally by `buildSlackMetaForPersistence` inside
1534
- // `persistQueuedMessageBody`.
1535
- const slackMeta = buildSlackMetaForPersistence({
1536
- slackInbound: options?.slackInbound,
1537
- turnChannel: conversation.getTurnChannelContext()?.userMessageChannel,
1538
- });
1539
-
1540
- if (slashResult.kind === "unknown") {
1541
- const serverTurnCtx = conversation.getTurnChannelContext();
1542
- const serverProvenance = provenanceFromTrustContext(
1543
- conversation.trustContext,
1544
- );
1545
- const imageSourcePaths: Record<string, string> = {};
1546
- for (let i = 0; i < attachments.length; i++) {
1547
- const a = attachments[i];
1548
- if (a.filePath && a.mimeType.toLowerCase().startsWith("image/")) {
1549
- imageSourcePaths[`${i}:${a.filename}`] = a.filePath;
1550
- }
1551
- }
1552
- const serverChannelMeta = {
1553
- ...serverProvenance,
1554
- ...(serverTurnCtx
1555
- ? {
1556
- userMessageChannel: serverTurnCtx.userMessageChannel,
1557
- assistantMessageChannel: serverTurnCtx.assistantMessageChannel,
1558
- }
1559
- : {}),
1560
- ...(serverInterfaceCtx
1561
- ? {
1562
- userMessageInterface: serverInterfaceCtx.userMessageInterface,
1563
- assistantMessageInterface:
1564
- serverInterfaceCtx.assistantMessageInterface,
1565
- }
1566
- : {}),
1567
- ...(Object.keys(imageSourcePaths).length > 0
1568
- ? { imageSourcePaths }
1569
- : {}),
1570
- };
1571
- // slackMeta encodes the inbound user message's ts/thread — it attaches
1572
- // to the user row only. The assistant's slash-command response does not
1573
- // originate from Slack and must not inherit the user's channelTs, which
1574
- // would break ordering in the chronological renderer.
1575
- const userMetaWithSlack = slackMeta
1576
- ? { ...serverChannelMeta, slackMeta }
1577
- : serverChannelMeta;
1578
- const cleanMsg = createUserMessage(content, attachments);
1579
- const llmMsg = enrichMessageWithSourcePaths(cleanMsg, attachments);
1580
- const persisted = await addMessage(
1581
- conversationId,
1582
- "user",
1583
- JSON.stringify(cleanMsg.content),
1584
- userMetaWithSlack,
1585
- );
1586
- conversation.getMessages().push(llmMsg);
1587
-
1588
- if (serverTurnCtx) {
1589
- try {
1590
- setConversationOriginChannelIfUnset(
1591
- conversationId,
1592
- serverTurnCtx.userMessageChannel,
1593
- );
1594
- } catch (err) {
1595
- log.warn(
1596
- { err, conversationId },
1597
- "Failed to set origin channel (best-effort)",
1598
- );
1599
- }
1600
- }
1601
- if (serverInterfaceCtx) {
1602
- try {
1603
- setConversationOriginInterfaceIfUnset(
1604
- conversationId,
1605
- serverInterfaceCtx.userMessageInterface,
1606
- );
1607
- } catch (err) {
1608
- log.warn(
1609
- { err, conversationId },
1610
- "Failed to set origin interface (best-effort)",
1611
- );
1612
- }
1613
- }
1614
-
1615
- // Rewrite meta.json so the on-disk metadata reflects the origin channel
1616
- if (serverTurnCtx || serverInterfaceCtx) {
1617
- try {
1618
- const convForMeta = getConversation(conversationId);
1619
- if (convForMeta) {
1620
- updateMetaFile(convForMeta);
1621
- }
1622
- } catch (err) {
1623
- log.warn(
1624
- { err, conversationId },
1625
- "Failed to update disk meta (best-effort)",
1626
- );
1627
- }
1628
- }
1629
-
1630
- const assistantMsg = createAssistantMessage(slashResult.message);
1631
- await addMessage(
1632
- conversationId,
1633
- "assistant",
1634
- JSON.stringify(assistantMsg.content),
1635
- serverChannelMeta,
1636
- );
1637
- conversation.getMessages().push(assistantMsg);
1638
- return { messageId: persisted.id };
1639
- }
1640
-
1641
- if (slashResult.kind === "compact") {
1642
- const serverTurnCtx = conversation.getTurnChannelContext();
1643
- const serverProvenance = provenanceFromTrustContext(
1644
- conversation.trustContext,
1645
- );
1646
- const compactChannelMeta = {
1647
- ...serverProvenance,
1648
- ...(serverTurnCtx
1649
- ? {
1650
- userMessageChannel: serverTurnCtx.userMessageChannel,
1651
- assistantMessageChannel: serverTurnCtx.assistantMessageChannel,
1652
- }
1653
- : {}),
1654
- ...(serverInterfaceCtx
1655
- ? {
1656
- userMessageInterface: serverInterfaceCtx.userMessageInterface,
1657
- assistantMessageInterface:
1658
- serverInterfaceCtx.assistantMessageInterface,
1659
- }
1660
- : {}),
1661
- };
1662
- const compactUserMeta = slackMeta
1663
- ? { ...compactChannelMeta, slackMeta }
1664
- : compactChannelMeta;
1665
- const cleanMsg = createUserMessage(content, attachments);
1666
- const persisted = await addMessage(
1667
- conversationId,
1668
- "user",
1669
- JSON.stringify(cleanMsg.content),
1670
- compactUserMeta,
1671
- );
1672
- conversation.getMessages().push(cleanMsg);
1673
-
1674
- conversation.emitActivityState(
1675
- "thinking",
1676
- "context_compacting",
1677
- "assistant_turn",
1678
- );
1679
- const result = await conversation.forceCompact();
1680
- const responseText = formatCompactResult(result);
1681
- const assistantMsg = createAssistantMessage(responseText);
1682
- await addMessage(
1683
- conversationId,
1684
- "assistant",
1685
- JSON.stringify(assistantMsg.content),
1686
- compactChannelMeta,
1687
- );
1688
- conversation.getMessages().push(assistantMsg);
1689
- return { messageId: persisted.id };
1690
- }
1691
-
1692
- const resolvedContent = slashResult.content;
1693
-
1694
- const requestId = crypto.randomUUID();
1695
- // Slack inbound metadata captured at the channel ingress boundary is
1696
- // forwarded into the persistence call so `persistQueuedMessageBody` can
1697
- // emit a `slackMeta` envelope on the row's metadata column.
1698
- const persistMetadata = options?.slackInbound
1699
- ? { slackInbound: options.slackInbound }
1700
- : undefined;
1701
- const messageId = await conversation.persistUserMessage(
1702
- resolvedContent,
1703
- attachments,
1704
- requestId,
1705
- persistMetadata,
1706
- );
1707
-
1708
- // Register pending interactions so channel approval interception can
1709
- // find the conversation by requestId when confirmation/secret events fire.
1710
- const registrar = makePendingInteractionRegistrar(
1711
- conversation,
1712
- conversationId,
1713
- );
1714
- const onEvent = options?.onEvent
1715
- ? (msg: ServerMessage) => {
1716
- registrar(msg);
1717
- try {
1718
- options.onEvent!(msg);
1719
- } catch (err) {
1720
- log.error(
1721
- { err, conversationId },
1722
- "onEvent callback failed; continuing agent loop",
1723
- );
1724
- }
1725
- }
1726
- : registrar;
1727
- if (options?.isInteractive === true) {
1728
- conversation.updateClient(onEvent, false);
1729
- }
1730
-
1731
- try {
1732
- await conversation.runAgentLoop(resolvedContent, messageId, onEvent, {
1733
- isInteractive: options?.isInteractive ?? false,
1734
- isUserMessage: true,
1735
- ...(options?.callSite ? { callSite: options.callSite } : {}),
1736
- });
1737
- } finally {
1738
- if (
1739
- options?.isInteractive === true &&
1740
- conversation.getCurrentSender() === onEvent
1741
- ) {
1742
- conversation.updateClient(() => {}, true);
1743
- }
1744
- }
1745
-
1746
- return { messageId };
1747
- }
1748
-
1749
819
  /**
1750
820
  * Expose conversation lookup for the POST /v1/messages handler.
1751
821
  * The handler manages busy-state checking and queueing itself.
@@ -1754,44 +824,7 @@ export class DaemonServer {
1754
824
  conversationId: string,
1755
825
  options?: ConversationCreateOptions,
1756
826
  ): Promise<Conversation> {
1757
- return this.getOrCreateConversation(conversationId, options);
1758
- }
1759
-
1760
- /**
1761
- * Look up an active conversation by ID without creating one.
1762
- */
1763
- findConversation(conversationId: string): Conversation | undefined {
1764
- return this.conversations.get(conversationId);
1765
- }
1766
-
1767
- /**
1768
- * Look up an active conversation that owns a given surfaceId.
1769
- */
1770
- findConversationBySurfaceId(surfaceId: string): Conversation | undefined {
1771
- // Fast path: exact surfaceId match in surfaceState
1772
- for (const c of this.conversations.values()) {
1773
- if (c.surfaceState.has(surfaceId)) return c;
1774
- }
1775
-
1776
- // Fallback: standalone app surfaces use "app-open-{appId}" IDs that
1777
- // were never part of any conversation. Extract the appId and find
1778
- // a conversation whose surfaceState has a surface for that app.
1779
- const appOpenPrefix = "app-open-";
1780
- if (surfaceId.startsWith(appOpenPrefix)) {
1781
- const appId = surfaceId.slice(appOpenPrefix.length);
1782
- for (const c of this.conversations.values()) {
1783
- for (const [, state] of c.surfaceState.entries()) {
1784
- const data = state.data as unknown as Record<string, unknown>;
1785
- if (data?.appId === appId) {
1786
- // Register this surfaceId so subsequent lookups are O(1)
1787
- c.surfaceState.set(surfaceId, state);
1788
- return c;
1789
- }
1790
- }
1791
- }
1792
- }
1793
-
1794
- return undefined;
827
+ return getOrCreateActiveConversation(conversationId, options);
1795
828
  }
1796
829
 
1797
830
  /**
@@ -1811,231 +844,3 @@ function extractConversationId(msg: ServerMessage): string | undefined {
1811
844
  }
1812
845
  return undefined;
1813
846
  }
1814
-
1815
- /**
1816
- * Translate a raw {@link AgentEvent} from the agent loop into the
1817
- * corresponding {@link ServerMessage} wire frame. The normal user-turn
1818
- * path does this via the full state-aware handler in
1819
- * `conversation-agent-loop-handlers.ts`; the wake path has no tool
1820
- * accounting, title generation, or activity-state tracking to worry
1821
- * about, so we only need the subset that produces client-visible
1822
- * frames. Events that have no client-visible wire shape (usage, error,
1823
- * preview/input-json deltas, etc.) are dropped — they produce no UI.
1824
- *
1825
- * Keeping this translator co-located with the wake adapter preserves
1826
- * the runtime/daemon layering: `runtime/agent-wake.ts` never imports
1827
- * `message-protocol.ts` or wire shapes, and the daemon owns all
1828
- * translation from agent-loop semantics to client frames.
1829
- */
1830
- function translateAgentEventToServerMessage(
1831
- event: AgentEvent,
1832
- conversationId: string,
1833
- ): ServerMessage | null {
1834
- switch (event.type) {
1835
- case "text_delta":
1836
- return {
1837
- type: "assistant_text_delta",
1838
- text: event.text,
1839
- conversationId,
1840
- };
1841
- case "thinking_delta":
1842
- return {
1843
- type: "assistant_thinking_delta",
1844
- thinking: event.thinking,
1845
- conversationId,
1846
- };
1847
- case "tool_use":
1848
- return {
1849
- type: "tool_use_start",
1850
- toolName: event.name,
1851
- input: event.input,
1852
- conversationId,
1853
- toolUseId: event.id,
1854
- };
1855
- case "tool_use_preview_start":
1856
- return {
1857
- type: "tool_use_preview_start",
1858
- toolUseId: event.toolUseId,
1859
- toolName: event.toolName,
1860
- conversationId,
1861
- };
1862
- case "tool_output_chunk":
1863
- return {
1864
- type: "tool_output_chunk",
1865
- chunk: event.chunk,
1866
- conversationId,
1867
- toolUseId: event.toolUseId,
1868
- };
1869
- case "tool_result": {
1870
- const imageBlocks = event.contentBlocks?.filter(
1871
- (b): b is Extract<typeof b, { type: "image" }> => b.type === "image",
1872
- );
1873
- const imageDataList = imageBlocks?.length
1874
- ? imageBlocks.map((b) => b.source.data)
1875
- : undefined;
1876
- return {
1877
- type: "tool_result",
1878
- toolName: "",
1879
- result: event.content,
1880
- isError: event.isError,
1881
- diff: event.diff,
1882
- status: event.status,
1883
- conversationId,
1884
- imageData: imageDataList?.[0],
1885
- imageDataList,
1886
- toolUseId: event.toolUseId,
1887
- };
1888
- }
1889
- case "server_tool_start":
1890
- return {
1891
- type: "tool_use_start",
1892
- toolName: event.name,
1893
- input: event.input,
1894
- conversationId,
1895
- toolUseId: event.toolUseId,
1896
- };
1897
- case "server_tool_complete": {
1898
- let resultText = "";
1899
- if (Array.isArray(event.content) && event.content.length > 0) {
1900
- resultText = (event.content as unknown[])
1901
- .filter(
1902
- (r): r is { type: string; title: string; url: string } =>
1903
- typeof r === "object" &&
1904
- r != null &&
1905
- (r as { type?: string }).type === "web_search_result",
1906
- )
1907
- .map((r) => `${r.title}\n${r.url}`)
1908
- .join("\n\n");
1909
- }
1910
- return {
1911
- type: "tool_result",
1912
- toolName: "web_search",
1913
- result: resultText,
1914
- isError: event.isError,
1915
- conversationId,
1916
- toolUseId: event.toolUseId,
1917
- };
1918
- }
1919
- case "message_complete":
1920
- return {
1921
- type: "message_complete",
1922
- conversationId,
1923
- };
1924
- // No wire frame for these — usage/error/input_json_delta are either
1925
- // server-internal (accounting/classification) or app-only debug
1926
- // streams the client doesn't surface for wake-originated turns.
1927
- case "input_json_delta":
1928
- case "usage":
1929
- case "error":
1930
- return null;
1931
- }
1932
- }
1933
-
1934
- /**
1935
- * Adapt a live {@link Conversation} to the narrow {@link WakeTarget}
1936
- * surface expected by `wakeAgentForOpportunity()`. Kept here so the
1937
- * runtime-level wake helper stays decoupled from the heavyweight
1938
- * conversation class (see `registerDefaultWakeResolver` above).
1939
- *
1940
- * Routing notes:
1941
- * - `emitAgentEvent` dispatches via `broadcastToAllClients` rather
1942
- * than `sendToClient`. Several signal-injected paths reset
1943
- * `sendToClient` to a no-op in their `finally` blocks (see the
1944
- * `updateClient(() => {}, true)` calls in `persistAndProcessMessage`
1945
- * / `processMessage`), so a wake fired on such a conversation would
1946
- * find a silent sink. `broadcastToAllClients` is wired to
1947
- * `this.broadcast(msg)` at construction time and always reaches the
1948
- * hub, regardless of which sender the most-recent user turn left
1949
- * behind.
1950
- * - `persistTailMessage` mirrors the canonical user-turn handlers
1951
- * (`handleMessageComplete` / the tool-result block in
1952
- * `conversation-agent-loop-handlers.ts`): builds channel/interface
1953
- * metadata via `provenanceFromTrustContext` plus the live turn
1954
- * channel/interface contexts, persists with metadata, and syncs the
1955
- * resulting row to the disk view so wake-produced messages appear
1956
- * in the on-disk transcript and carry provenance tags.
1957
- * - `drainQueue` delegates to the conversation so any user messages
1958
- * queued while the wake was running are processed. The wake helper
1959
- * calls this in its finally AFTER `markProcessing(false)`; the
1960
- * order matters because `enqueueMessage` only queues when
1961
- * `processing === true`.
1962
- */
1963
- function conversationToWakeTarget(conversation: Conversation): WakeTarget {
1964
- return {
1965
- conversationId: conversation.conversationId,
1966
- agentLoop: conversation.agentLoop,
1967
- getMessages: () => conversation.getMessages(),
1968
- pushMessage: (msg) => {
1969
- conversation.messages.push(msg);
1970
- },
1971
- emitAgentEvent: (event) => {
1972
- const frame = translateAgentEventToServerMessage(
1973
- event,
1974
- conversation.conversationId,
1975
- );
1976
- if (!frame) return;
1977
- // Prefer `broadcastToAllClients` (wired to the hub at construction
1978
- // time and always live) over `sendToClient` (which several
1979
- // signal-injected paths reset to `() => {}` in their finally
1980
- // blocks). Fall back to `sendToClient` when the broadcaster is
1981
- // missing (e.g. in tests that construct a Conversation directly).
1982
- if (conversation.broadcastToAllClients) {
1983
- conversation.broadcastToAllClients(frame);
1984
- } else {
1985
- conversation.sendToClient(frame);
1986
- }
1987
- },
1988
- isProcessing: () => conversation.isProcessing(),
1989
- markProcessing: (on) => {
1990
- conversation.processing = on;
1991
- },
1992
- persistTailMessage: async (message) => {
1993
- // Build metadata that mirrors the canonical handlers in
1994
- // `conversation-agent-loop-handlers.ts`. If the live turn channel
1995
- // / interface contexts are missing (a wake can fire on a
1996
- // conversation that has never run a user turn), fall back to the
1997
- // conversation's origin channel/interface defaults (`"vellum"`)
1998
- // so persisted rows still carry valid channel/interface ids.
1999
- const turnChannelCtx = conversation.getTurnChannelContext();
2000
- const turnInterfaceCtx = conversation.getTurnInterfaceContext();
2001
- const metadata: Record<string, unknown> = {
2002
- ...provenanceFromTrustContext(conversation.trustContext),
2003
- userMessageChannel: turnChannelCtx?.userMessageChannel ?? "vellum",
2004
- assistantMessageChannel:
2005
- turnChannelCtx?.assistantMessageChannel ?? "vellum",
2006
- userMessageInterface:
2007
- turnInterfaceCtx?.userMessageInterface ?? "vellum",
2008
- assistantMessageInterface:
2009
- turnInterfaceCtx?.assistantMessageInterface ?? "vellum",
2010
- };
2011
- const persisted = await addMessage(
2012
- conversation.conversationId,
2013
- message.role,
2014
- JSON.stringify(message.content),
2015
- metadata,
2016
- );
2017
- // Sync the persisted row to the disk view so wake-produced
2018
- // messages appear in the on-disk transcript and tools that read
2019
- // from disk (e.g. `messages.jsonl`-based diagnostics) see them.
2020
- // Mirrors the `syncMessageToDisk(...)` calls in the canonical
2021
- // handlers — best-effort because a sync failure must not strand
2022
- // the in-memory tail.
2023
- try {
2024
- const convRow = getConversation(conversation.conversationId);
2025
- if (convRow) {
2026
- syncMessageToDisk(
2027
- conversation.conversationId,
2028
- persisted.id,
2029
- convRow.createdAt,
2030
- );
2031
- }
2032
- } catch (err) {
2033
- log.warn(
2034
- { err, conversationId: conversation.conversationId },
2035
- "wake adapter: syncMessageToDisk failed (non-fatal)",
2036
- );
2037
- }
2038
- },
2039
- drainQueue: () => conversation.drainQueue(),
2040
- };
2041
- }