@vellumai/assistant 0.6.6 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1603) hide show
  1. package/AGENTS.md +20 -0
  2. package/ARCHITECTURE.md +46 -38
  3. package/Dockerfile +27 -6
  4. package/README.md +9 -11
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +83 -149
  6. package/bun.lock +309 -119
  7. package/docs/architecture/memory.md +1 -90
  8. package/docs/architecture/security.md +28 -41
  9. package/docs/credential-execution-service.md +7 -5
  10. package/docs/skills.md +10 -10
  11. package/docs/stt-provider-onboarding.md +17 -45
  12. package/examples/plugins/echo/bun.lock +25 -0
  13. package/knip.json +9 -22
  14. package/node_modules/@vellumai/ces-client/bun.lock +33 -0
  15. package/node_modules/@vellumai/ces-client/package.json +25 -0
  16. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +631 -0
  17. package/node_modules/@vellumai/ces-client/src/__tests__/package-boundary.test.ts +138 -0
  18. package/node_modules/@vellumai/ces-client/src/credential-rpc.ts +13 -0
  19. package/node_modules/@vellumai/ces-client/src/http-credentials.ts +296 -0
  20. package/node_modules/@vellumai/ces-client/src/http-log-export.ts +111 -0
  21. package/node_modules/@vellumai/ces-client/src/index.ts +43 -0
  22. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +445 -0
  23. package/node_modules/@vellumai/credential-storage/src/__tests__/package-boundary.test.ts +32 -6
  24. package/node_modules/@vellumai/egress-proxy/src/__tests__/package-boundary.test.ts +32 -1
  25. package/node_modules/@vellumai/gateway-client/bun.lock +39 -0
  26. package/node_modules/@vellumai/gateway-client/package.json +23 -0
  27. package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +343 -0
  28. package/node_modules/@vellumai/gateway-client/src/__tests__/package-boundary.test.ts +140 -0
  29. package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +422 -0
  30. package/node_modules/@vellumai/gateway-client/src/index.ts +35 -0
  31. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +331 -0
  32. package/node_modules/@vellumai/gateway-client/src/types.ts +131 -0
  33. package/node_modules/@vellumai/gateway-client/tsconfig.json +20 -0
  34. package/node_modules/@vellumai/{ces-contracts → service-contracts}/bun.lock +1 -1
  35. package/node_modules/@vellumai/{ces-contracts → service-contracts}/package.json +4 -2
  36. package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/contracts.test.ts +5 -1
  37. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +155 -0
  38. package/node_modules/@vellumai/service-contracts/src/credential-rpc.ts +23 -0
  39. package/node_modules/@vellumai/service-contracts/src/index.ts +25 -0
  40. package/node_modules/@vellumai/{ces-contracts/src/index.ts → service-contracts/src/transport.ts} +6 -28
  41. package/node_modules/@vellumai/service-contracts/src/trust-rules.ts +116 -0
  42. package/node_modules/@vellumai/service-contracts/tsconfig.json +20 -0
  43. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +887 -0
  44. package/node_modules/@vellumai/skill-host-contracts/bun.lock +24 -0
  45. package/node_modules/@vellumai/skill-host-contracts/package.json +18 -0
  46. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +86 -0
  47. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +1342 -0
  48. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +6 -0
  49. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +11 -0
  50. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +32 -0
  51. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +325 -0
  52. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +444 -0
  53. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +20 -0
  54. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +12 -0
  55. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  56. package/node_modules/@vellumai/slack-text/package.json +18 -0
  57. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  58. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  59. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  60. package/openapi.yaml +3136 -650
  61. package/package.json +15 -7
  62. package/scripts/check-circular-deps.ts +80 -0
  63. package/scripts/generate-openapi.ts +29 -107
  64. package/{src/memory/graph/inspect.ts → scripts/memory-inspect.ts} +27 -27
  65. package/src/__tests__/access-request-decision.test.ts +2 -11
  66. package/src/__tests__/acp-session.test.ts +4 -150
  67. package/src/__tests__/actor-token-service.test.ts +17 -678
  68. package/src/__tests__/agent-loop-callsite-precedence.test.ts +2 -6
  69. package/src/__tests__/agent-loop-override-profile.test.ts +404 -0
  70. package/src/__tests__/agent-loop-thinking.test.ts +4 -4
  71. package/src/__tests__/agent-wake-override-profile.test.ts +283 -0
  72. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -1
  73. package/src/__tests__/anthropic-provider.test.ts +183 -28
  74. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  75. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  76. package/src/__tests__/app-routes-csp.test.ts +106 -55
  77. package/src/__tests__/approval-cascade.test.ts +3 -370
  78. package/src/__tests__/approval-conversation-turn.test.ts +3 -8
  79. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
  80. package/src/__tests__/approval-primitive.test.ts +2 -1
  81. package/src/__tests__/approval-routes-http.test.ts +36 -464
  82. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  83. package/src/__tests__/assistant-event.test.ts +0 -5
  84. package/src/__tests__/assistant-events-sse-hardening.test.ts +107 -92
  85. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  86. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -3
  87. package/src/__tests__/attachment-upload-trusted-source.test.ts +139 -0
  88. package/src/__tests__/attachments-store.test.ts +46 -1
  89. package/src/__tests__/audit-log-rotation.test.ts +2 -1
  90. package/src/__tests__/auto-analysis-end-to-end.test.ts +8 -20
  91. package/src/__tests__/background-shell-bash.test.ts +227 -0
  92. package/src/__tests__/background-shell-host-bash.test.ts +465 -0
  93. package/src/__tests__/background-tool-registry.test.ts +145 -0
  94. package/src/__tests__/background-tool-routes.test.ts +175 -0
  95. package/src/__tests__/btw-routes.test.ts +147 -183
  96. package/src/__tests__/call-controller.test.ts +15 -2
  97. package/src/__tests__/call-conversation-messages.test.ts +2 -1
  98. package/src/__tests__/call-domain.test.ts +2 -2
  99. package/src/__tests__/call-pointer-messages.test.ts +11 -13
  100. package/src/__tests__/call-recovery.test.ts +2 -1
  101. package/src/__tests__/call-routes-http.test.ts +3 -14
  102. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  103. package/src/__tests__/call-store.test.ts +2 -1
  104. package/src/__tests__/cancel-resolves-conversation-key.test.ts +31 -62
  105. package/src/__tests__/canonical-guardian-store.test.ts +2 -2
  106. package/src/__tests__/catalog-files.test.ts +0 -26
  107. package/src/__tests__/ces-rpc-credential-backend.test.ts +1 -1
  108. package/src/__tests__/channel-approval-routes.test.ts +88 -344
  109. package/src/__tests__/channel-approval.test.ts +9 -7
  110. package/src/__tests__/channel-approvals.test.ts +34 -197
  111. package/src/__tests__/channel-delivery-store.test.ts +11 -10
  112. package/src/__tests__/channel-guardian.test.ts +114 -171
  113. package/src/__tests__/channel-readiness-service.test.ts +8 -6
  114. package/src/__tests__/channel-reply-delivery.test.ts +3 -19
  115. package/src/__tests__/channel-retry-sweep.test.ts +2 -5
  116. package/src/__tests__/checker.test.ts +272 -3933
  117. package/src/__tests__/circuit-breaker-pipeline.test.ts +1 -1
  118. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +208 -0
  119. package/src/__tests__/cli.test.ts +1 -38
  120. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  121. package/src/__tests__/compaction-events.test.ts +2 -1
  122. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  123. package/src/__tests__/compaction-strip-metadata-clear.test.ts +2 -2
  124. package/src/__tests__/compaction-timeout-recovery.test.ts +1 -1
  125. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -7
  126. package/src/__tests__/config-model-image-provider.test.ts +0 -1
  127. package/src/__tests__/config-schema-cmd.test.ts +1 -1
  128. package/src/__tests__/config-schema.test.ts +36 -269
  129. package/src/__tests__/config-watcher.test.ts +12 -0
  130. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -25
  131. package/src/__tests__/connection-policy.test.ts +1 -52
  132. package/src/__tests__/contact-store-user-file.test.ts +2 -1
  133. package/src/__tests__/contacts-tools.test.ts +56 -29
  134. package/src/__tests__/contacts-write.test.ts +8 -125
  135. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  136. package/src/__tests__/context-search-agent-protocol.test.ts +230 -0
  137. package/src/__tests__/context-search-agent-runner.test.ts +998 -0
  138. package/src/__tests__/context-search-conversations-source.test.ts +320 -0
  139. package/src/__tests__/context-search-fanout.test.ts +380 -0
  140. package/src/__tests__/context-search-memory-source.test.ts +430 -0
  141. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  142. package/src/__tests__/context-search-pkb-source.test.ts +493 -0
  143. package/src/__tests__/context-search-types.test.ts +95 -0
  144. package/src/__tests__/context-search-workspace-source.test.ts +532 -0
  145. package/src/__tests__/context-window-manager.test.ts +71 -0
  146. package/src/__tests__/conversation-abort-tool-results.test.ts +10 -1
  147. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +633 -0
  148. package/src/__tests__/conversation-agent-loop-overflow.test.ts +117 -31
  149. package/src/__tests__/conversation-agent-loop.test.ts +1004 -15
  150. package/src/__tests__/conversation-analysis-routes.test.ts +68 -88
  151. package/src/__tests__/conversation-attachments.test.ts +9 -20
  152. package/src/__tests__/conversation-attention-store.test.ts +2 -1
  153. package/src/__tests__/conversation-attention-telegram.test.ts +15 -5
  154. package/src/__tests__/conversation-clear-safety.test.ts +53 -95
  155. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -330
  156. package/src/__tests__/conversation-crud-inference-profile.test.ts +54 -0
  157. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +63 -157
  158. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  159. package/src/__tests__/conversation-disk-view.test.ts +5 -4
  160. package/src/__tests__/conversation-fork-crud.test.ts +26 -55
  161. package/src/__tests__/conversation-fork-route.test.ts +5 -74
  162. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  163. package/src/__tests__/conversation-inference-profile-list.test.ts +128 -0
  164. package/src/__tests__/conversation-inference-profile-route.test.ts +205 -0
  165. package/src/__tests__/conversation-init.benchmark.test.ts +4 -81
  166. package/src/__tests__/conversation-key-store-disk-view.test.ts +2 -1
  167. package/src/__tests__/conversation-lifecycle.test.ts +4 -5
  168. package/src/__tests__/conversation-list-source.test.ts +2 -2
  169. package/src/__tests__/conversation-load-history-repair.test.ts +0 -1
  170. package/src/__tests__/conversation-pairing.test.ts +0 -1
  171. package/src/__tests__/conversation-pre-run-repair.test.ts +137 -297
  172. package/src/__tests__/conversation-process-callsite.test.ts +79 -3
  173. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -1
  174. package/src/__tests__/conversation-queue.test.ts +4 -41
  175. package/src/__tests__/conversation-routes-disk-view.test.ts +55 -188
  176. package/src/__tests__/conversation-routes-guardian-reply.test.ts +64 -71
  177. package/src/__tests__/conversation-routes-slash-commands.test.ts +144 -64
  178. package/src/__tests__/conversation-runtime-assembly.test.ts +295 -84
  179. package/src/__tests__/conversation-slash-commands.test.ts +30 -47
  180. package/src/__tests__/conversation-slash-queue.test.ts +2 -1
  181. package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
  182. package/src/__tests__/conversation-speed-override.test.ts +0 -4
  183. package/src/__tests__/conversation-starter-routes.test.ts +254 -55
  184. package/src/__tests__/conversation-starters-cadence.test.ts +2 -2
  185. package/src/__tests__/conversation-store.test.ts +2 -375
  186. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  187. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  188. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  189. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +9 -47
  190. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +6 -6
  191. package/src/__tests__/conversation-unread-route.test.ts +1 -1
  192. package/src/__tests__/conversation-usage.test.ts +255 -4
  193. package/src/__tests__/conversation-wipe.test.ts +2 -103
  194. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -1
  195. package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
  196. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
  197. package/src/__tests__/conversations-defer-cli.test.ts +150 -0
  198. package/src/__tests__/credential-execution-admin-cli.test.ts +1 -1
  199. package/src/__tests__/credential-execution-api-key-propagation.test.ts +2 -2
  200. package/src/__tests__/credential-execution-approval-bridge.test.ts +22 -289
  201. package/src/__tests__/credential-execution-client.test.ts +1 -1
  202. package/src/__tests__/credential-execution-managed-contract.test.ts +1 -1
  203. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  204. package/src/__tests__/credential-health-service.test.ts +68 -0
  205. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  206. package/src/__tests__/credential-security-invariants.test.ts +15 -5
  207. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  208. package/src/__tests__/credentials-cli.test.ts +45 -21
  209. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  210. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  211. package/src/__tests__/daemon-credential-client.test.ts +26 -108
  212. package/src/__tests__/db-acp-history.test.ts +284 -0
  213. package/src/__tests__/db-activation-state.test.ts +240 -0
  214. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  215. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +2 -1
  216. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +248 -0
  217. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +2 -1
  218. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +116 -0
  219. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  220. package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +132 -0
  221. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  222. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  223. package/src/__tests__/delete-propagation.test.ts +3 -2
  224. package/src/__tests__/deterministic-verification-control-plane.test.ts +38 -104
  225. package/src/__tests__/dm-backfill.test.ts +3 -2
  226. package/src/__tests__/document-conversations.test.ts +332 -0
  227. package/src/__tests__/edit-propagation.test.ts +5 -7
  228. package/src/__tests__/embedding-managed-proxy-selection.test.ts +3 -3
  229. package/src/__tests__/emit-event-signal.test.ts +4 -6
  230. package/src/__tests__/empty-response-pipeline.test.ts +1 -1
  231. package/src/__tests__/events-client-registration.test.ts +441 -0
  232. package/src/__tests__/file-write-tool.test.ts +2 -4
  233. package/src/__tests__/filing-service.test.ts +197 -19
  234. package/src/__tests__/first-greeting.test.ts +156 -150
  235. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  236. package/src/__tests__/followup-tools.test.ts +2 -1
  237. package/src/__tests__/gateway-client-managed-outbound.test.ts +8 -12
  238. package/src/__tests__/gateway-only-enforcement.test.ts +2 -6
  239. package/src/__tests__/gateway-only-guard.test.ts +4 -3
  240. package/src/__tests__/gemini-provider.test.ts +276 -10
  241. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  242. package/src/__tests__/graph-extraction-event-date.test.ts +30 -0
  243. package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -1
  244. package/src/__tests__/guardian-action-followup-executor.test.ts +2 -2
  245. package/src/__tests__/guardian-action-followup-store.test.ts +2 -1
  246. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +9 -9
  247. package/src/__tests__/guardian-action-late-reply.test.ts +2 -1
  248. package/src/__tests__/guardian-action-store.test.ts +2 -1
  249. package/src/__tests__/guardian-action-sweep.test.ts +9 -8
  250. package/src/__tests__/guardian-binding-drift-heal.test.ts +3 -2
  251. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +21 -118
  252. package/src/__tests__/guardian-dispatch.test.ts +14 -11
  253. package/src/__tests__/guardian-grant-minting.test.ts +16 -17
  254. package/src/__tests__/guardian-outbound-http.test.ts +71 -106
  255. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -2
  256. package/src/__tests__/guardian-routing-invariants.test.ts +41 -92
  257. package/src/__tests__/guardian-routing-state.test.ts +15 -23
  258. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -2
  259. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +274 -0
  260. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -87
  261. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  262. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  263. package/src/__tests__/heartbeat-service.test.ts +325 -25
  264. package/src/__tests__/helpers/call-route-handler.ts +72 -0
  265. package/src/__tests__/helpers/channel-test-adapter.ts +161 -0
  266. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  267. package/src/__tests__/helpers/gateway-classify-mock.ts +67 -0
  268. package/src/__tests__/helpers/mock-logger.ts +36 -0
  269. package/src/__tests__/history-repair-pipeline.test.ts +1 -1
  270. package/src/__tests__/home-state-routes.test.ts +10 -31
  271. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  272. package/src/__tests__/host-browser-e2e-cloud.test.ts +38 -498
  273. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +35 -95
  274. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  275. package/src/__tests__/host-browser-routes.test.ts +68 -153
  276. package/src/__tests__/host-browser-ws-events-e2e.test.ts +35 -31
  277. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  278. package/src/__tests__/host-file-proxy.test.ts +44 -98
  279. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  280. package/src/__tests__/host-proxy-interface.test.ts +3 -3
  281. package/src/__tests__/host-shell-tool.test.ts +35 -72
  282. package/src/__tests__/host-transfer-pending-interactions.test.ts +144 -0
  283. package/src/__tests__/host-transfer-proxy.test.ts +723 -0
  284. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  285. package/src/__tests__/http-user-message-parity.test.ts +18 -15
  286. package/src/__tests__/inbound-invite-redemption.test.ts +3 -2
  287. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  288. package/src/__tests__/injector-chain.test.ts +25 -21
  289. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  290. package/src/__tests__/inline-command-runner.test.ts +0 -66
  291. package/src/__tests__/inline-skill-load-permissions.test.ts +41 -208
  292. package/src/__tests__/install-skill-routing.test.ts +2 -14
  293. package/src/__tests__/invite-redemption-service.test.ts +2 -1
  294. package/src/__tests__/invite-routes-http.test.ts +80 -12
  295. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +2 -1
  296. package/src/__tests__/jobs-store-upsert-debounced.test.ts +2 -1
  297. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +157 -0
  298. package/src/__tests__/list-messages-attachments.test.ts +52 -55
  299. package/src/__tests__/list-messages-page-latest.test.ts +283 -0
  300. package/src/__tests__/list-messages-tool-merge.test.ts +16 -17
  301. package/src/__tests__/llm-call-pipeline.test.ts +7 -8
  302. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  303. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  304. package/src/__tests__/llm-context-normalization.test.ts +69 -4
  305. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  306. package/src/__tests__/llm-context-route-provider.test.ts +39 -113
  307. package/src/__tests__/llm-request-log-turn-query.test.ts +2 -1
  308. package/src/__tests__/llm-resolver.test.ts +279 -0
  309. package/src/__tests__/llm-schema.test.ts +57 -1
  310. package/src/__tests__/llm-usage-store.test.ts +271 -5
  311. package/src/__tests__/log-export-routes.test.ts +89 -0
  312. package/src/__tests__/log-export-workspace.test.ts +28 -17
  313. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  314. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  315. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  316. package/src/__tests__/mcp-abort-signal.test.ts +2 -3
  317. package/src/__tests__/mcp-client-auth.test.ts +2 -3
  318. package/src/__tests__/memory-admin-recall.test.ts +221 -0
  319. package/src/__tests__/memory-recall-log-store.test.ts +2 -1
  320. package/src/__tests__/memory-retrieval-pipeline.test.ts +6 -8
  321. package/src/__tests__/memory-upsert-concurrency.test.ts +2 -1
  322. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  323. package/src/__tests__/migration-cross-version-compatibility.test.ts +209 -302
  324. package/src/__tests__/migration-export-http.test.ts +50 -43
  325. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  326. package/src/__tests__/migration-export-to-gcs.test.ts +531 -0
  327. package/src/__tests__/migration-import-commit-http.test.ts +82 -37
  328. package/src/__tests__/migration-import-from-gcs.test.ts +574 -0
  329. package/src/__tests__/migration-import-from-url.test.ts +34 -27
  330. package/src/__tests__/migration-import-preflight-http.test.ts +108 -108
  331. package/src/__tests__/migration-jobs-status.test.ts +164 -0
  332. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  333. package/src/__tests__/migration-transport.test.ts +115 -23
  334. package/src/__tests__/migration-validate-http.test.ts +149 -159
  335. package/src/__tests__/migration-wizard.test.ts +133 -27
  336. package/src/__tests__/mock-gateway-ipc.ts +32 -62
  337. package/src/__tests__/model-intents.test.ts +15 -2
  338. package/src/__tests__/nl-approval-parser.test.ts +13 -17
  339. package/src/__tests__/non-member-access-request.test.ts +14 -6
  340. package/src/__tests__/notification-guardian-path.test.ts +15 -8
  341. package/src/__tests__/notification-schedule-notify-dedup.test.ts +2 -1
  342. package/src/__tests__/notification-telegram-adapter.test.ts +57 -55
  343. package/src/__tests__/oauth-apps-routes.test.ts +76 -122
  344. package/src/__tests__/oauth-cli.test.ts +14 -1
  345. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  346. package/src/__tests__/oauth-provider-visibility.test.ts +3 -1
  347. package/src/__tests__/oauth-providers-routes.test.ts +78 -101
  348. package/src/__tests__/oauth-store.test.ts +22 -1
  349. package/src/__tests__/oauth2-gateway-transport.test.ts +6 -3
  350. package/src/__tests__/openai-provider.test.ts +105 -6
  351. package/src/__tests__/openai-responses-provider.test.ts +146 -4
  352. package/src/__tests__/openrouter-provider-only.test.ts +22 -4
  353. package/src/__tests__/overflow-reduce-pipeline.test.ts +4 -9
  354. package/src/__tests__/permission-types.test.ts +3 -18
  355. package/src/__tests__/persistence-pipeline.test.ts +3 -2
  356. package/src/__tests__/pipeline-runner.test.ts +1 -1
  357. package/src/__tests__/platform-bash-auto-approve.test.ts +44 -28
  358. package/src/__tests__/platform.test.ts +11 -63
  359. package/src/__tests__/playbook-execution.test.ts +2 -1
  360. package/src/__tests__/playbook-tools.test.ts +2 -1
  361. package/src/__tests__/plugin-bootstrap.test.ts +51 -5
  362. package/src/__tests__/plugin-registry.test.ts +30 -0
  363. package/src/__tests__/plugin-route-contribution.test.ts +17 -11
  364. package/src/__tests__/plugin-skill-contribution.test.ts +3 -3
  365. package/src/__tests__/plugin-tool-contribution.test.ts +10 -4
  366. package/src/__tests__/plugin-types.test.ts +1 -1
  367. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  368. package/src/__tests__/pricing.test.ts +218 -5
  369. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  370. package/src/__tests__/profiler-routes.test.ts +112 -177
  371. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  372. package/src/__tests__/provider-send-message-override-profile.test.ts +273 -0
  373. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  374. package/src/__tests__/proxy-approval-callback.test.ts +6 -554
  375. package/src/__tests__/qdrant-collection-migration.test.ts +7 -7
  376. package/src/__tests__/reaction-persistence.test.ts +12 -8
  377. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  378. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  379. package/src/__tests__/recording-handler.test.ts +64 -83
  380. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  381. package/src/__tests__/registry.test.ts +1 -0
  382. package/src/__tests__/relay-server.test.ts +37 -17
  383. package/src/__tests__/require-fresh-approval.test.ts +24 -182
  384. package/src/__tests__/resolve-trust-class.test.ts +2 -1
  385. package/src/__tests__/retry-thinking-tool-choice.test.ts +19 -7
  386. package/src/__tests__/retry-verbosity-normalization.test.ts +139 -0
  387. package/src/__tests__/runtime-attachment-metadata.test.ts +26 -6
  388. package/src/__tests__/runtime-events-sse-parity.test.ts +15 -17
  389. package/src/__tests__/runtime-events-sse.test.ts +16 -33
  390. package/src/__tests__/schedule-routes.test.ts +226 -129
  391. package/src/__tests__/schedule-store.test.ts +119 -1
  392. package/src/__tests__/schedule-tools.test.ts +2 -1
  393. package/src/__tests__/scheduler-recurrence.test.ts +2 -1
  394. package/src/__tests__/scheduler-reuse-conversation.test.ts +2 -1
  395. package/src/__tests__/scheduler-wake.test.ts +356 -0
  396. package/src/__tests__/scoped-approval-grants.test.ts +2 -1
  397. package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -1
  398. package/src/__tests__/search-skills-unified.test.ts +9 -15
  399. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  400. package/src/__tests__/secret-ingress-http.test.ts +36 -23
  401. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  402. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  403. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  404. package/src/__tests__/secret-response-routing.test.ts +29 -15
  405. package/src/__tests__/secret-routes-managed-proxy.test.ts +51 -103
  406. package/src/__tests__/secret-scanner.test.ts +2 -545
  407. package/src/__tests__/send-endpoint-busy.test.ts +36 -38
  408. package/src/__tests__/sequence-store.test.ts +2 -1
  409. package/src/__tests__/server-history-render.test.ts +2 -2
  410. package/src/__tests__/service-contracts-import-guard.test.ts +185 -0
  411. package/src/__tests__/set-permission-mode.test.ts +0 -10
  412. package/src/__tests__/settings-routes.test.ts +36 -69
  413. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  414. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  415. package/src/__tests__/skill-boundary-guard.test.ts +105 -0
  416. package/src/__tests__/skill-load-inline-command.test.ts +2 -2
  417. package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
  418. package/src/__tests__/skill-runtime-path.test.ts +64 -0
  419. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  420. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  421. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -32
  422. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  423. package/src/__tests__/slack-inbound-verification.test.ts +12 -64
  424. package/src/__tests__/slack-messaging-token-resolution.test.ts +1 -3
  425. package/src/__tests__/slack-reaction-approvals.test.ts +4 -4
  426. package/src/__tests__/slack-share-routes.test.ts +37 -72
  427. package/src/__tests__/subagent-call-site-routing.test.ts +79 -0
  428. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  429. package/src/__tests__/subagent-fork-spawn.test.ts +20 -28
  430. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  431. package/src/__tests__/subagent-notify-parent.test.ts +83 -109
  432. package/src/__tests__/subagent-role-registry.test.ts +3 -3
  433. package/src/__tests__/subagent-spawn-tool-fork.test.ts +52 -104
  434. package/src/__tests__/subagent-tools.test.ts +0 -1
  435. package/src/__tests__/suggestion-routes.test.ts +55 -62
  436. package/src/__tests__/system-prompt.test.ts +115 -13
  437. package/src/__tests__/task-compiler.test.ts +2 -1
  438. package/src/__tests__/task-management-tools.test.ts +2 -1
  439. package/src/__tests__/task-memory-cleanup.test.ts +2 -1
  440. package/src/__tests__/task-scheduler.test.ts +2 -1
  441. package/src/__tests__/telegram-config.test.ts +0 -1
  442. package/src/__tests__/terminal-tools.test.ts +3 -401
  443. package/src/__tests__/test-preload.ts +0 -11
  444. package/src/__tests__/thread-backfill.test.ts +947 -32
  445. package/src/__tests__/token-estimate-pipeline.test.ts +68 -15
  446. package/src/__tests__/tool-approval-handler.test.ts +21 -63
  447. package/src/__tests__/tool-audit-listener.test.ts +3 -3
  448. package/src/__tests__/tool-domain-event-publisher.test.ts +3 -39
  449. package/src/__tests__/tool-error-pipeline.test.ts +6 -6
  450. package/src/__tests__/tool-execute-pipeline.test.ts +6 -14
  451. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  452. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +69 -16
  453. package/src/__tests__/tool-executor-lifecycle-events.test.ts +31 -62
  454. package/src/__tests__/tool-executor.test.ts +336 -1654
  455. package/src/__tests__/tool-grant-request-escalation.test.ts +90 -311
  456. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  457. package/src/__tests__/tool-result-truncate-pipeline.test.ts +1 -1
  458. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  459. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  460. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  461. package/src/__tests__/trust-context-guards.test.ts +1 -1
  462. package/src/__tests__/trusted-contact-approval-notifier.test.ts +7 -15
  463. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +178 -354
  464. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +5 -151
  465. package/src/__tests__/trusted-contact-multichannel.test.ts +5 -6
  466. package/src/__tests__/trusted-contact-verification.test.ts +3 -2
  467. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  468. package/src/__tests__/turn-boundary-resolution.test.ts +2 -1
  469. package/src/__tests__/twilio-routes.test.ts +25 -66
  470. package/src/__tests__/usage-attribution.test.ts +247 -0
  471. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -7
  472. package/src/__tests__/usage-cli.test.ts +143 -0
  473. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  474. package/src/__tests__/usage-routes.test.ts +223 -90
  475. package/src/__tests__/user-plugin-loader.test.ts +54 -12
  476. package/src/__tests__/validation-results-screen.test.ts +39 -16
  477. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  478. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +51 -139
  479. package/src/__tests__/verification-control-plane-policy.test.ts +97 -19
  480. package/src/__tests__/voice-ingress-preflight.test.ts +5 -5
  481. package/src/__tests__/voice-invite-redemption.test.ts +2 -1
  482. package/src/__tests__/voice-scoped-grant-consumer.test.ts +3 -3
  483. package/src/__tests__/voice-session-bridge.test.ts +285 -106
  484. package/src/__tests__/volume-security-guard.test.ts +0 -2
  485. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -1
  486. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +3 -1
  487. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +2 -1
  488. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +1 -1
  489. package/src/__tests__/workspace-migration-052-seed-default-inference-profiles.test.ts +260 -0
  490. package/src/__tests__/workspace-migration-053-release-notes-acp-codex.test.ts +225 -0
  491. package/src/__tests__/workspace-migration-054-seed-recall-callsite.test.ts +235 -0
  492. package/src/__tests__/workspace-migration-055-release-notes-agentic-recall.test.ts +128 -0
  493. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +232 -0
  494. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  495. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  496. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  497. package/src/__tests__/workspace-migration-acp-sessions-ui.test.ts +144 -0
  498. package/src/__tests__/workspace-migration-drop-user-md.test.ts +1 -1
  499. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +252 -0
  500. package/src/acp/__tests__/client-handler.test.ts +64 -0
  501. package/src/acp/__tests__/helpers/acp-config-stub.ts +62 -0
  502. package/src/acp/__tests__/helpers/which-stub.ts +45 -0
  503. package/src/acp/__tests__/session-manager-persistence.test.ts +366 -0
  504. package/src/acp/__tests__/session-manager-startup.test.ts +159 -0
  505. package/src/acp/__tests__/session-manager.test.ts +83 -0
  506. package/src/acp/client-handler.ts +23 -139
  507. package/src/acp/index.ts +0 -15
  508. package/src/acp/resolve-agent.test.ts +291 -0
  509. package/src/acp/resolve-agent.ts +176 -0
  510. package/src/acp/session-manager.ts +193 -31
  511. package/src/acp/types.ts +2 -50
  512. package/src/agent/loop.ts +53 -15
  513. package/src/agent/message-types.ts +0 -2
  514. package/src/approvals/AGENTS.md +5 -1
  515. package/src/approvals/__tests__/guardian-feed-event.test.ts +11 -12
  516. package/src/approvals/approval-primitive.ts +3 -20
  517. package/src/approvals/guardian-decision-primitive.ts +37 -68
  518. package/src/approvals/guardian-request-resolvers.ts +38 -104
  519. package/src/avatar/character-components.ts +6 -6
  520. package/src/{config/bundled-skills/settings/tools → avatar}/identity-avatar.ts +1 -1
  521. package/src/backup/__tests__/backup-worker.test.ts +36 -10
  522. package/src/backup/__tests__/paths.test.ts +5 -4
  523. package/src/backup/__tests__/restore.test.ts +45 -28
  524. package/src/backup/backup-worker.ts +37 -12
  525. package/src/backup/paths.ts +11 -24
  526. package/src/backup/restore.ts +7 -11
  527. package/src/browser/__tests__/operations.test.ts +0 -35
  528. package/src/browser/operations.ts +1 -47
  529. package/src/browser-session/events.ts +0 -9
  530. package/src/bundler/package-resolver.ts +2 -6
  531. package/src/calls/active-call-lease.ts +1 -1
  532. package/src/calls/call-constants.ts +1 -1
  533. package/src/calls/call-controller.ts +1 -5
  534. package/src/calls/call-domain.ts +14 -14
  535. package/src/calls/call-pointer-messages.ts +4 -9
  536. package/src/calls/call-store.ts +2 -34
  537. package/src/calls/guardian-action-sweep.ts +9 -25
  538. package/src/calls/guardian-dispatch.ts +1 -20
  539. package/src/calls/guardian-question-copy.ts +0 -108
  540. package/src/calls/media-stream-audio-transcode.ts +2 -41
  541. package/src/calls/media-stream-server.ts +2 -3
  542. package/src/calls/media-stream-stt-session.ts +1 -3
  543. package/src/calls/relay-access-wait.ts +5 -8
  544. package/src/calls/relay-server.ts +15 -42
  545. package/src/calls/relay-setup-router.ts +2 -2
  546. package/src/calls/relay-verification.ts +4 -4
  547. package/src/calls/twilio-rest.ts +1 -39
  548. package/src/calls/twilio-routes.ts +160 -78
  549. package/src/calls/voice-control-protocol.ts +10 -10
  550. package/src/calls/voice-ingress-preflight.ts +2 -2
  551. package/src/calls/voice-session-bridge.ts +141 -77
  552. package/src/channels/__tests__/types.test.ts +25 -3
  553. package/src/channels/permission-profiles.ts +2 -72
  554. package/src/channels/types.ts +25 -44
  555. package/src/cli/AGENTS.md +1 -0
  556. package/src/cli/__tests__/notifications.test.ts +12 -10
  557. package/src/cli/commands/__tests__/attachment.test.ts +14 -8
  558. package/src/cli/commands/__tests__/backup.test.ts +3 -14
  559. package/src/cli/commands/__tests__/browser.test.ts +36 -31
  560. package/src/cli/commands/__tests__/cache.test.ts +175 -23
  561. package/src/cli/commands/__tests__/memory-v2.test.ts +382 -0
  562. package/src/cli/commands/__tests__/task.test.ts +36 -35
  563. package/src/cli/commands/__tests__/trust.test.ts +236 -0
  564. package/src/cli/commands/__tests__/ui-confirm.test.ts +14 -14
  565. package/src/cli/commands/__tests__/ui.test.ts +17 -17
  566. package/src/cli/commands/__tests__/watchers.test.ts +29 -29
  567. package/src/cli/commands/__tests__/webhooks.test.ts +544 -0
  568. package/src/cli/commands/attachment.ts +12 -8
  569. package/src/cli/commands/auth.ts +1 -1
  570. package/src/cli/commands/avatar.ts +192 -9
  571. package/src/cli/commands/backup.ts +18 -48
  572. package/src/cli/commands/browser.ts +52 -4
  573. package/src/cli/commands/cache-fs.ts +8 -0
  574. package/src/cli/commands/cache.ts +157 -84
  575. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  576. package/src/cli/commands/clients.ts +74 -17
  577. package/src/cli/commands/completions.ts +3 -3
  578. package/src/cli/commands/contacts.ts +241 -86
  579. package/src/cli/commands/conversations-defer.ts +364 -0
  580. package/src/cli/commands/conversations-import.ts +2 -3
  581. package/src/cli/commands/conversations.ts +63 -53
  582. package/src/cli/commands/credential-execution.ts +1 -1
  583. package/src/cli/commands/credentials.ts +139 -5
  584. package/src/cli/commands/default-action.ts +1 -1
  585. package/src/cli/commands/domain.ts +2 -2
  586. package/src/cli/commands/email.ts +7 -7
  587. package/src/cli/commands/image-generation.ts +1 -1
  588. package/src/cli/commands/keys.ts +5 -2
  589. package/src/cli/commands/mcp.ts +1 -1
  590. package/src/cli/commands/memory-v2.ts +315 -0
  591. package/src/cli/commands/memory.ts +8 -8
  592. package/src/cli/commands/notifications.ts +21 -20
  593. package/src/cli/commands/oauth/__tests__/connect.test.ts +23 -5
  594. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +1 -1
  595. package/src/cli/commands/oauth/__tests__/mode.test.ts +1 -1
  596. package/src/cli/commands/oauth/__tests__/status.test.ts +1 -1
  597. package/src/cli/commands/oauth/__tests__/token.test.ts +1 -1
  598. package/src/cli/commands/oauth/connect.ts +2 -2
  599. package/src/cli/commands/pending.ts +102 -0
  600. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -6
  601. package/src/cli/commands/platform/__tests__/connect.test.ts +23 -11
  602. package/src/cli/commands/platform/__tests__/disconnect.test.ts +22 -10
  603. package/src/cli/commands/platform/__tests__/status.test.ts +22 -10
  604. package/src/cli/commands/platform/connect.ts +3 -3
  605. package/src/cli/commands/platform/disconnect.ts +4 -6
  606. package/src/cli/commands/platform/index.ts +12 -10
  607. package/src/cli/commands/routes.ts +7 -1
  608. package/src/cli/commands/sequence.ts +7 -7
  609. package/src/cli/commands/skills.ts +264 -116
  610. package/src/cli/commands/task.ts +12 -10
  611. package/src/cli/commands/trust.ts +105 -167
  612. package/src/cli/commands/ui.ts +3 -3
  613. package/src/cli/commands/usage.ts +29 -15
  614. package/src/cli/commands/watchers.ts +8 -8
  615. package/src/cli/commands/webhooks.ts +270 -0
  616. package/src/cli/lib/daemon-avatar-client.ts +37 -0
  617. package/src/cli/lib/daemon-credential-client.ts +41 -189
  618. package/src/cli/lib/ipc-params.ts +22 -0
  619. package/src/cli/program.ts +6 -0
  620. package/src/cli.ts +1 -82
  621. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  622. package/src/config/acp-defaults.test.ts +57 -0
  623. package/src/config/acp-defaults.ts +40 -0
  624. package/src/config/acp-schema.ts +1 -1
  625. package/src/config/assistant-feature-flags.ts +18 -142
  626. package/src/config/bundled-skills/acp/SKILL.md +44 -16
  627. package/src/config/bundled-skills/acp/TOOLS.json +45 -1
  628. package/src/config/bundled-skills/acp/tools/acp-list-agents.ts +12 -0
  629. package/src/config/bundled-skills/acp/tools/acp-steer.ts +12 -0
  630. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +14 -14
  631. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -4
  632. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +11 -6
  633. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +6 -6
  634. package/src/config/bundled-skills/media-processing/services/reduce.ts +0 -13
  635. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  636. package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +1 -1
  637. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
  638. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -1
  639. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +1 -1
  640. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -1
  641. package/src/config/bundled-skills/settings/SKILL.md +2 -17
  642. package/src/config/bundled-skills/settings/TOOLS.json +0 -56
  643. package/src/config/bundled-skills/subagent/SKILL.md +2 -0
  644. package/src/config/bundled-tool-registry.ts +4 -6
  645. package/src/config/env-registry.ts +12 -2
  646. package/src/config/env.ts +10 -22
  647. package/src/config/feature-flag-registry.json +38 -46
  648. package/src/config/llm-callsite-catalog.ts +12 -0
  649. package/src/config/llm-context-resolution.ts +80 -0
  650. package/src/config/llm-resolver.ts +90 -36
  651. package/src/config/loader.ts +9 -12
  652. package/src/config/schema.ts +5 -228
  653. package/src/config/schemas/__tests__/filing.test.ts +58 -0
  654. package/src/config/schemas/__tests__/memory-v2.test.ts +187 -0
  655. package/src/config/schemas/call-site-catalog.ts +271 -0
  656. package/src/config/schemas/calls.ts +5 -5
  657. package/src/config/schemas/filing.ts +12 -0
  658. package/src/config/schemas/host-browser.ts +2 -2
  659. package/src/config/schemas/inference.ts +1 -3
  660. package/src/config/schemas/ingress.ts +2 -2
  661. package/src/config/schemas/llm.ts +82 -12
  662. package/src/config/schemas/memory-retrieval.ts +2 -2
  663. package/src/config/schemas/memory-storage.ts +1 -1
  664. package/src/config/schemas/memory-v2.ts +185 -0
  665. package/src/config/schemas/memory.ts +2 -0
  666. package/src/config/schemas/security.ts +1 -102
  667. package/src/config/schemas/services.ts +52 -13
  668. package/src/config/schemas/skills.ts +5 -5
  669. package/src/config/schemas/tts.ts +1 -1
  670. package/src/config/seed-inference-profiles.ts +117 -0
  671. package/src/config/skills.ts +1 -91
  672. package/src/config/types.ts +3 -47
  673. package/src/contacts/contact-store.ts +2 -19
  674. package/src/contacts/contacts-write.ts +1 -143
  675. package/src/contacts/types.ts +8 -10
  676. package/src/context/token-estimator.ts +1 -1
  677. package/src/context/tool-result-truncation.ts +1 -1
  678. package/src/context/window-manager.ts +45 -6
  679. package/src/credential-execution/approval-bridge.ts +7 -69
  680. package/src/credential-execution/client.ts +17 -422
  681. package/src/credential-execution/feature-gates.ts +1 -2
  682. package/src/credential-execution/managed-catalog.ts +1 -1
  683. package/src/credential-execution/process-manager.ts +34 -10
  684. package/src/credential-health/credential-health-service.ts +22 -17
  685. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -13
  686. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +76 -83
  687. package/src/daemon/__tests__/daemon-skill-host.test.ts +265 -0
  688. package/src/daemon/__tests__/meet-host-supervisor.test.ts +587 -0
  689. package/src/daemon/__tests__/meet-manifest-loader.test.ts +463 -0
  690. package/src/daemon/approval-generators.ts +2 -14
  691. package/src/daemon/classifier.ts +0 -106
  692. package/src/daemon/config-watcher.ts +14 -54
  693. package/src/daemon/connection-policy.ts +1 -40
  694. package/src/daemon/conversation-agent-loop-handlers.ts +89 -9
  695. package/src/daemon/conversation-agent-loop.ts +440 -88
  696. package/src/daemon/conversation-attachments.ts +5 -81
  697. package/src/daemon/conversation-error.ts +9 -5
  698. package/src/daemon/conversation-history.ts +9 -9
  699. package/src/daemon/conversation-launch.ts +21 -136
  700. package/src/daemon/conversation-lifecycle.ts +1 -1
  701. package/src/daemon/conversation-messaging.ts +2 -1
  702. package/src/daemon/conversation-notifiers.ts +1 -1
  703. package/src/daemon/conversation-process.ts +90 -174
  704. package/src/daemon/conversation-runtime-assembly.ts +245 -164
  705. package/src/daemon/conversation-slash.ts +50 -164
  706. package/src/daemon/conversation-store.ts +344 -0
  707. package/src/daemon/conversation-surfaces.ts +27 -32
  708. package/src/daemon/conversation-tool-setup.ts +23 -202
  709. package/src/daemon/conversation-usage.ts +36 -0
  710. package/src/daemon/conversation.ts +129 -381
  711. package/src/daemon/daemon-control.ts +4 -72
  712. package/src/daemon/daemon-skill-host.ts +259 -0
  713. package/src/daemon/dictation-profile-store.ts +2 -26
  714. package/src/daemon/external-plugins-bootstrap.ts +67 -13
  715. package/src/daemon/first-greeting.ts +44 -156
  716. package/src/daemon/handlers/config-channels.ts +14 -14
  717. package/src/daemon/handlers/config-embeddings.ts +1 -1
  718. package/src/daemon/handlers/config-ingress.ts +27 -166
  719. package/src/daemon/handlers/config-model.test.ts +17 -0
  720. package/src/daemon/handlers/config-model.ts +8 -53
  721. package/src/daemon/handlers/config-telegram.ts +6 -53
  722. package/src/daemon/handlers/config-voice.ts +0 -42
  723. package/src/daemon/handlers/conversations.ts +32 -345
  724. package/src/daemon/handlers/recording.ts +27 -159
  725. package/src/daemon/handlers/shared.ts +50 -99
  726. package/src/daemon/handlers/skills.ts +55 -114
  727. package/src/daemon/host-bash-proxy.ts +67 -45
  728. package/src/daemon/host-browser-proxy.ts +65 -27
  729. package/src/daemon/host-cu-proxy.ts +40 -39
  730. package/src/daemon/host-file-proxy.ts +58 -37
  731. package/src/daemon/host-transfer-proxy.ts +538 -0
  732. package/src/daemon/lifecycle.ts +71 -272
  733. package/src/daemon/meet-host-startup.ts +51 -0
  734. package/src/daemon/meet-host-supervisor.ts +781 -0
  735. package/src/daemon/meet-manifest-loader.ts +410 -0
  736. package/src/daemon/memory-v2-startup.ts +35 -0
  737. package/src/daemon/message-protocol.ts +4 -7
  738. package/src/daemon/message-types/acp.ts +1 -0
  739. package/src/daemon/message-types/conversations.ts +23 -2
  740. package/src/daemon/message-types/host-bash.ts +1 -0
  741. package/src/daemon/message-types/host-cu.ts +1 -0
  742. package/src/daemon/message-types/host-file.ts +1 -0
  743. package/src/daemon/message-types/host-transfer.ts +42 -0
  744. package/src/daemon/message-types/integrations.ts +6 -0
  745. package/src/daemon/message-types/messages.ts +24 -23
  746. package/src/daemon/message-types/schedules.ts +1 -0
  747. package/src/daemon/message-types/settings.ts +0 -6
  748. package/src/daemon/message-types/shared.ts +5 -2
  749. package/src/daemon/message-types/subagents.ts +2 -1
  750. package/src/daemon/message-types/workspace.ts +1 -3
  751. package/src/daemon/pkb-reminder-builder.test.ts +13 -12
  752. package/src/daemon/pkb-reminder-builder.ts +8 -16
  753. package/src/daemon/process-message.ts +479 -0
  754. package/src/daemon/providers-setup.ts +14 -6
  755. package/src/daemon/server.ts +58 -1702
  756. package/src/daemon/shutdown-handlers.ts +3 -3
  757. package/src/daemon/startup-error.ts +1 -1
  758. package/src/daemon/tool-side-effects.ts +125 -107
  759. package/src/daemon/trust-context.ts +45 -0
  760. package/src/daemon/wake-target-adapter.ts +218 -0
  761. package/src/email/feature-gate.ts +1 -1
  762. package/src/events/domain-events.ts +1 -16
  763. package/src/events/tool-audit-listener.ts +5 -9
  764. package/src/events/tool-domain-event-publisher.ts +0 -10
  765. package/src/events/tool-metrics-listener.ts +1 -21
  766. package/src/events/tool-trace-listener.ts +0 -14
  767. package/src/filing/filing-service.ts +207 -55
  768. package/src/followups/followup-store.ts +3 -71
  769. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +93 -21
  770. package/src/heartbeat/heartbeat-service.ts +55 -16
  771. package/src/home/__tests__/feed-writer.test.ts +0 -4
  772. package/src/home/__tests__/phase5-exit-criteria.test.ts +18 -1
  773. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  774. package/src/home/__tests__/rollup-producer.test.ts +67 -2
  775. package/src/home/assistant-feed-authoring.ts +8 -1
  776. package/src/home/feed-types.ts +1 -1
  777. package/src/home/feed-writer.ts +1 -2
  778. package/src/home/relationship-state-writer.ts +17 -4
  779. package/src/home/rewrite-feed-title.ts +58 -0
  780. package/src/home/rollup-producer.ts +16 -3
  781. package/src/inbound/platform-callback-registration.ts +1 -17
  782. package/src/ipc/__tests__/attachment-ipc.test.ts +128 -66
  783. package/src/ipc/__tests__/browser-ipc.test.ts +72 -58
  784. package/src/ipc/__tests__/cache-ipc.test.ts +52 -107
  785. package/src/ipc/__tests__/cli-ipc.test.ts +9 -6
  786. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +253 -0
  787. package/src/ipc/__tests__/skill-server.test.ts +182 -0
  788. package/src/ipc/__tests__/socket-path.test.ts +69 -23
  789. package/src/ipc/__tests__/ui-request-route.test.ts +241 -216
  790. package/src/ipc/__tests__/watcher-ipc.test.ts +33 -33
  791. package/src/ipc/assistant-server.ts +443 -0
  792. package/src/ipc/cli-client.ts +3 -3
  793. package/src/ipc/gateway-client.test.ts +131 -0
  794. package/src/ipc/gateway-client.ts +98 -123
  795. package/src/ipc/ipc-framing.ts +281 -0
  796. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +171 -0
  797. package/src/ipc/routes/db-proxy.ts +73 -0
  798. package/src/ipc/routes/route-adapter.ts +32 -0
  799. package/src/ipc/routes/trust-rules.test.ts +123 -0
  800. package/src/ipc/skill-ipc-types.ts +54 -0
  801. package/src/ipc/skill-routes/__tests__/config.test.ts +146 -0
  802. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +388 -0
  803. package/src/ipc/skill-routes/__tests__/identity.test.ts +62 -0
  804. package/src/ipc/skill-routes/__tests__/log.test.ts +133 -0
  805. package/src/ipc/skill-routes/__tests__/memory.test.ts +178 -0
  806. package/src/ipc/skill-routes/__tests__/platform.test.ts +111 -0
  807. package/src/ipc/skill-routes/__tests__/providers.test.ts +265 -0
  808. package/src/ipc/skill-routes/__tests__/registries.test.ts +361 -0
  809. package/src/ipc/skill-routes/config.ts +47 -0
  810. package/src/ipc/skill-routes/events.ts +120 -0
  811. package/src/ipc/skill-routes/identity.ts +21 -0
  812. package/src/ipc/skill-routes/index.ts +37 -0
  813. package/src/ipc/skill-routes/log.ts +40 -0
  814. package/src/ipc/skill-routes/memory.ts +76 -0
  815. package/src/ipc/skill-routes/platform.ts +39 -0
  816. package/src/ipc/skill-routes/providers.ts +163 -0
  817. package/src/ipc/skill-routes/registries.ts +393 -0
  818. package/src/ipc/skill-server.ts +738 -0
  819. package/src/ipc/skill-socket-path.ts +20 -0
  820. package/src/ipc/socket-cleanup.ts +92 -0
  821. package/src/ipc/socket-path.ts +63 -32
  822. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +374 -0
  823. package/src/live-voice/__tests__/live-voice-archive.test.ts +525 -0
  824. package/src/live-voice/__tests__/live-voice-events.test.ts +473 -0
  825. package/src/live-voice/__tests__/live-voice-integration.test.ts +359 -0
  826. package/src/live-voice/__tests__/live-voice-metrics.test.ts +179 -0
  827. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +349 -0
  828. package/src/live-voice/__tests__/live-voice-stt.test.ts +244 -0
  829. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +337 -0
  830. package/src/live-voice/__tests__/live-voice-tts.test.ts +337 -0
  831. package/src/live-voice/__tests__/protocol.test.ts +295 -0
  832. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +413 -0
  833. package/src/live-voice/live-voice-archive.ts +758 -0
  834. package/src/live-voice/live-voice-metrics.ts +472 -0
  835. package/src/live-voice/live-voice-session-manager.ts +222 -0
  836. package/src/live-voice/live-voice-session.ts +1144 -0
  837. package/src/live-voice/live-voice-tts.ts +260 -0
  838. package/src/live-voice/protocol.ts +515 -0
  839. package/src/mcp/client.ts +2 -2
  840. package/src/mcp/manager.ts +0 -5
  841. package/src/media/types.ts +4 -4
  842. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +4 -28
  843. package/src/memory/__tests__/auto-analysis-guard.test.ts +2 -2
  844. package/src/memory/__tests__/conversation-analyze-job.test.ts +7 -62
  845. package/src/memory/__tests__/conversation-group-migration.test.ts +2 -2
  846. package/src/memory/__tests__/find-analysis-conversation.test.ts +2 -1
  847. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  848. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +235 -0
  849. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  850. package/src/memory/admin.ts +65 -7
  851. package/src/memory/app-git-service.ts +0 -46
  852. package/src/memory/app-store.ts +154 -0
  853. package/src/memory/attachments-store.ts +20 -16
  854. package/src/memory/auto-analysis-enqueue.ts +2 -17
  855. package/src/memory/canonical-guardian-store.ts +2 -1
  856. package/src/memory/channel-verification-sessions.ts +1 -1
  857. package/src/memory/checkpoints.ts +1 -1
  858. package/src/memory/context-search/agent-protocol.ts +424 -0
  859. package/src/memory/context-search/agent-runner.ts +1295 -0
  860. package/src/memory/context-search/format.ts +160 -0
  861. package/src/memory/context-search/limits.ts +106 -0
  862. package/src/memory/context-search/search.ts +387 -0
  863. package/src/memory/context-search/sources/conversations.ts +278 -0
  864. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  865. package/src/memory/context-search/sources/memory.ts +95 -0
  866. package/src/memory/context-search/sources/pkb.ts +477 -0
  867. package/src/memory/context-search/sources/workspace.ts +1256 -0
  868. package/src/memory/context-search/types.ts +49 -0
  869. package/src/memory/conversation-analyze-job.ts +3 -24
  870. package/src/memory/conversation-attention-store.ts +1 -1
  871. package/src/memory/conversation-bootstrap.ts +1 -1
  872. package/src/memory/conversation-crud.ts +86 -119
  873. package/src/memory/conversation-directories.ts +1 -11
  874. package/src/memory/conversation-disk-view.ts +1 -5
  875. package/src/memory/conversation-display-order-migration.ts +11 -2
  876. package/src/memory/conversation-group-migration.ts +20 -4
  877. package/src/memory/conversation-key-store.ts +3 -4
  878. package/src/memory/conversation-queries.ts +13 -26
  879. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  880. package/src/memory/conversation-starter-validation.ts +88 -0
  881. package/src/memory/conversation-starters-cadence.ts +1 -1
  882. package/src/memory/conversation-title-service.ts +2 -1
  883. package/src/memory/db-connection.ts +62 -0
  884. package/src/memory/db-init.ts +28 -4
  885. package/src/memory/db-maintenance.ts +1 -1
  886. package/src/memory/delivery-channels.ts +1 -14
  887. package/src/memory/delivery-crud.ts +2 -32
  888. package/src/memory/delivery-status.ts +1 -1
  889. package/src/memory/embedding-backend.ts +3 -21
  890. package/src/memory/embedding-gemini.test.ts +4 -4
  891. package/src/memory/embedding-gemini.ts +0 -2
  892. package/src/memory/embedding-local.ts +6 -6
  893. package/src/memory/embedding-ollama.ts +6 -6
  894. package/src/memory/embedding-openai.ts +6 -6
  895. package/src/memory/embedding-types.ts +21 -0
  896. package/src/memory/external-conversation-store.ts +1 -1
  897. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +408 -0
  898. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +225 -0
  899. package/src/memory/graph/bootstrap.test.ts +2 -7
  900. package/src/memory/graph/bootstrap.ts +2 -1
  901. package/src/memory/graph/capability-seed.ts +3 -3
  902. package/src/memory/graph/compaction.ts +1 -1
  903. package/src/memory/graph/consolidation.ts +13 -10
  904. package/src/memory/graph/conversation-graph-memory.ts +184 -12
  905. package/src/memory/graph/decay.ts +1 -1
  906. package/src/memory/graph/extraction.ts +53 -21
  907. package/src/memory/graph/graph-memory-state-store.ts +1 -1
  908. package/src/memory/graph/graph-search.test.ts +94 -2
  909. package/src/memory/graph/graph-search.ts +22 -7
  910. package/src/memory/graph/image-ref-utils.ts +1 -1
  911. package/src/memory/graph/injection.test.ts +2 -2
  912. package/src/memory/graph/injection.ts +1 -1
  913. package/src/memory/graph/retriever.test.ts +158 -4
  914. package/src/memory/graph/retriever.ts +17 -5
  915. package/src/memory/graph/store.test.ts +2 -1
  916. package/src/memory/graph/store.ts +1 -1
  917. package/src/memory/graph/tool-handlers.ts +73 -247
  918. package/src/memory/graph/tools.ts +35 -53
  919. package/src/memory/group-crud.ts +1 -2
  920. package/src/memory/guardian-action-store.ts +2 -84
  921. package/src/memory/guardian-approvals.ts +1 -49
  922. package/src/memory/guardian-rate-limits.ts +1 -1
  923. package/src/memory/indexer.ts +44 -32
  924. package/src/memory/invite-store.ts +1 -1
  925. package/src/memory/job-handlers/backfill.ts +1 -1
  926. package/src/memory/job-handlers/cleanup.ts +2 -1
  927. package/src/memory/job-handlers/conversation-starters.ts +54 -63
  928. package/src/memory/job-handlers/embedding.test.ts +2 -1
  929. package/src/memory/job-handlers/embedding.ts +1 -1
  930. package/src/memory/job-handlers/index-maintenance.ts +1 -1
  931. package/src/memory/job-handlers/summarization.ts +3 -3
  932. package/src/memory/job-utils.ts +3 -9
  933. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +362 -0
  934. package/src/memory/jobs/embed-concept-page.ts +210 -0
  935. package/src/memory/jobs/embed-pkb-file.test.ts +2 -1
  936. package/src/memory/jobs-store.ts +9 -2
  937. package/src/memory/jobs-worker.ts +56 -17
  938. package/src/memory/lifecycle-events-store.ts +1 -1
  939. package/src/memory/llm-request-log-store.ts +1 -42
  940. package/src/memory/llm-usage-store.ts +130 -44
  941. package/src/memory/media-store.ts +1 -1
  942. package/src/memory/memory-recall-log-store.ts +1 -1
  943. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  944. package/src/memory/migrations/038-actor-token-records.ts +3 -0
  945. package/src/memory/migrations/039-actor-refresh-token-records.ts +3 -0
  946. package/src/memory/migrations/226-schedule-wake-conversation-id.ts +11 -0
  947. package/src/memory/migrations/227-add-conversation-inference-profile.ts +18 -0
  948. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +27 -0
  949. package/src/memory/migrations/229-delete-private-conversations.test.ts +1087 -0
  950. package/src/memory/migrations/229-delete-private-conversations.ts +210 -0
  951. package/src/memory/migrations/230-acp-session-history.ts +41 -0
  952. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +128 -0
  953. package/src/memory/migrations/232-activation-state.ts +38 -0
  954. package/src/memory/migrations/233-document-conversations.ts +54 -0
  955. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  956. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  957. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  958. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  959. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  960. package/src/memory/migrations/index.ts +24 -0
  961. package/src/memory/migrations/registry.ts +31 -0
  962. package/src/memory/pkb/pkb-index.test.ts +4 -5
  963. package/src/memory/pkb/pkb-reconcile.test.ts +4 -5
  964. package/src/memory/pkb/pkb-search.test.ts +83 -3
  965. package/src/memory/pkb/pkb-search.ts +27 -14
  966. package/src/memory/published-pages-store.ts +1 -1
  967. package/src/memory/raw-query.ts +2 -68
  968. package/src/memory/schema/acp.ts +30 -0
  969. package/src/memory/schema/conversations.ts +8 -1
  970. package/src/memory/schema/index.ts +1 -0
  971. package/src/memory/schema/infrastructure.ts +26 -32
  972. package/src/memory/schema/memory-graph.ts +36 -14
  973. package/src/memory/scoped-approval-grants.ts +2 -1
  974. package/src/memory/search/semantic.ts +7 -18
  975. package/src/memory/shared-app-links-store.ts +2 -1
  976. package/src/memory/tool-usage-store.ts +3 -1
  977. package/src/memory/trace-event-store.ts +2 -1
  978. package/src/memory/turn-events-store.ts +1 -1
  979. package/src/memory/usage-buckets.ts +40 -1
  980. package/src/memory/usage-grouped-buckets.ts +127 -0
  981. package/src/memory/v2/__tests__/activation-store.test.ts +202 -0
  982. package/src/memory/v2/__tests__/activation.test.ts +1155 -0
  983. package/src/memory/v2/__tests__/backfill-jobs.test.ts +483 -0
  984. package/src/memory/v2/__tests__/consolidation-job.test.ts +412 -0
  985. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  986. package/src/memory/v2/__tests__/injection.test.ts +1161 -0
  987. package/src/memory/v2/__tests__/migration.test.ts +840 -0
  988. package/src/memory/v2/__tests__/page-store.test.ts +517 -0
  989. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  990. package/src/memory/v2/__tests__/qdrant.test.ts +438 -0
  991. package/src/memory/v2/__tests__/sim.test.ts +549 -0
  992. package/src/memory/v2/__tests__/skill-content.test.ts +85 -0
  993. package/src/memory/v2/__tests__/skill-qdrant.test.ts +657 -0
  994. package/src/memory/v2/__tests__/skill-store.test.ts +463 -0
  995. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  996. package/src/memory/v2/__tests__/sweep-job.test.ts +441 -0
  997. package/src/memory/v2/activation-store.ts +109 -0
  998. package/src/memory/v2/activation.ts +561 -0
  999. package/src/memory/v2/backfill-jobs.ts +357 -0
  1000. package/src/memory/v2/consolidation-job.ts +306 -0
  1001. package/src/memory/v2/edge-index.ts +191 -0
  1002. package/src/memory/v2/injection.ts +431 -0
  1003. package/src/memory/v2/migration.ts +647 -0
  1004. package/src/memory/v2/now-text.ts +37 -0
  1005. package/src/memory/v2/page-store.ts +382 -0
  1006. package/src/memory/v2/prompts/consolidation.ts +261 -0
  1007. package/src/memory/v2/prompts/sweep.ts +56 -0
  1008. package/src/memory/v2/qdrant.ts +342 -0
  1009. package/src/memory/v2/sim.ts +206 -0
  1010. package/src/memory/v2/skill-content.ts +42 -0
  1011. package/src/memory/v2/skill-qdrant.ts +395 -0
  1012. package/src/memory/v2/skill-store.ts +176 -0
  1013. package/src/memory/v2/static-context.ts +62 -0
  1014. package/src/memory/v2/sweep-job.ts +298 -0
  1015. package/src/memory/v2/types.ts +106 -0
  1016. package/src/memory/validation.ts +0 -11
  1017. package/src/messaging/draft-store.ts +0 -6
  1018. package/src/messaging/provider-types.ts +8 -0
  1019. package/src/messaging/provider.ts +7 -0
  1020. package/src/messaging/providers/gmail/client.ts +1 -121
  1021. package/src/messaging/providers/index.ts +262 -0
  1022. package/src/messaging/providers/outlook/client.ts +0 -73
  1023. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  1024. package/src/messaging/providers/slack/adapter.ts +122 -21
  1025. package/src/messaging/providers/slack/api.ts +242 -0
  1026. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  1027. package/src/messaging/providers/slack/backfill.ts +89 -11
  1028. package/src/messaging/providers/slack/client.ts +10 -124
  1029. package/src/messaging/providers/slack/message-metadata.ts +13 -3
  1030. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  1031. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  1032. package/src/messaging/providers/slack/send.ts +383 -0
  1033. package/src/messaging/providers/slack/types.ts +1 -0
  1034. package/src/messaging/providers/telegram-bot/adapter.ts +4 -42
  1035. package/src/messaging/providers/telegram-bot/api.ts +253 -0
  1036. package/src/messaging/providers/telegram-bot/client.ts +17 -58
  1037. package/src/messaging/providers/telegram-bot/send.ts +232 -0
  1038. package/src/messaging/providers/whatsapp/adapter.ts +4 -36
  1039. package/src/messaging/providers/whatsapp/api.ts +319 -0
  1040. package/src/messaging/providers/whatsapp/client.ts +4 -48
  1041. package/src/messaging/providers/whatsapp/send.ts +209 -0
  1042. package/src/notifications/adapters/slack.ts +5 -23
  1043. package/src/notifications/adapters/telegram.ts +8 -29
  1044. package/src/notifications/conversation-candidates.ts +1 -1
  1045. package/src/notifications/conversation-seed-composer.ts +12 -6
  1046. package/src/notifications/copy-composer.ts +1 -1
  1047. package/src/notifications/decision-engine.ts +1 -1
  1048. package/src/notifications/decisions-store.ts +1 -1
  1049. package/src/notifications/deliveries-store.ts +2 -1
  1050. package/src/notifications/deterministic-checks.ts +1 -1
  1051. package/src/notifications/events-store.ts +1 -13
  1052. package/src/notifications/preferences-store.ts +1 -1
  1053. package/src/notifications/signal.ts +0 -9
  1054. package/src/oauth/connection-resolver.test.ts +8 -0
  1055. package/src/oauth/connection-resolver.ts +6 -5
  1056. package/src/oauth/credential-token-resolver.ts +97 -0
  1057. package/src/oauth/manual-token-connection.ts +30 -34
  1058. package/src/oauth/oauth-store.ts +8 -5
  1059. package/src/outbound-proxy/certs.ts +0 -7
  1060. package/src/outbound-proxy/config.ts +0 -74
  1061. package/src/outbound-proxy/health.ts +0 -44
  1062. package/src/outbound-proxy/index.ts +0 -23
  1063. package/src/permissions/approval-policy.test.ts +149 -132
  1064. package/src/permissions/approval-policy.ts +65 -91
  1065. package/src/permissions/approval-provenance.test.ts +184 -0
  1066. package/src/permissions/approval-provenance.ts +70 -0
  1067. package/src/permissions/checker.test.ts +632 -0
  1068. package/src/permissions/checker.ts +270 -460
  1069. package/src/permissions/gateway-threshold-reader.ts +31 -47
  1070. package/src/permissions/ipc-risk-types.ts +95 -0
  1071. package/src/permissions/prompter.ts +13 -11
  1072. package/src/permissions/risk-types.ts +24 -210
  1073. package/src/permissions/secret-prompter.ts +21 -48
  1074. package/src/permissions/types.ts +49 -46
  1075. package/src/permissions/workspace-policy.ts +1 -8
  1076. package/src/platform/sync-identity.ts +0 -8
  1077. package/src/playbooks/playbook-compiler.ts +1 -1
  1078. package/src/plugins/defaults/index.ts +1 -1
  1079. package/src/plugins/defaults/injectors.ts +87 -23
  1080. package/src/plugins/defaults/llm-call.ts +6 -9
  1081. package/src/plugins/defaults/memory-retrieval.ts +1 -6
  1082. package/src/plugins/defaults/overflow-reduce.ts +12 -7
  1083. package/src/plugins/defaults/token-estimate.ts +2 -3
  1084. package/src/plugins/registry.ts +61 -1
  1085. package/src/plugins/types.ts +14 -7
  1086. package/src/plugins/user-loader.ts +36 -10
  1087. package/src/prompts/persona-resolver.ts +2 -4
  1088. package/src/prompts/system-prompt.ts +34 -31
  1089. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  1090. package/src/prompts/templates/SOUL.md +3 -1
  1091. package/src/prompts/update-bulletin-job.ts +2 -0
  1092. package/src/providers/__tests__/provider-env-vars.test.ts +0 -21
  1093. package/src/providers/__tests__/retry-callsite.test.ts +141 -7
  1094. package/src/providers/anthropic/client.ts +143 -52
  1095. package/src/providers/call-site-routing.ts +49 -6
  1096. package/src/providers/fireworks/client.ts +3 -0
  1097. package/src/providers/gemini/client.ts +113 -23
  1098. package/src/providers/managed-proxy/context.ts +0 -17
  1099. package/src/providers/model-catalog.ts +188 -27
  1100. package/src/providers/model-intents.ts +7 -8
  1101. package/src/providers/openai/chat-completions-provider.ts +43 -7
  1102. package/src/providers/openai/responses-provider.ts +46 -5
  1103. package/src/providers/openrouter/client.ts +4 -5
  1104. package/src/providers/provider-env-vars.ts +4 -12
  1105. package/src/providers/provider-send-message.ts +61 -13
  1106. package/src/providers/ratelimit.ts +7 -2
  1107. package/src/providers/registry.ts +15 -10
  1108. package/src/providers/retry.ts +148 -31
  1109. package/src/providers/speech-to-text/openai-whisper-stream.ts +1 -1
  1110. package/src/providers/speech-to-text/openai-whisper.ts +3 -6
  1111. package/src/providers/speech-to-text/provider-catalog.ts +75 -0
  1112. package/src/providers/speech-to-text/xai.ts +5 -5
  1113. package/src/providers/thinking-config.ts +34 -0
  1114. package/src/providers/types.ts +35 -10
  1115. package/src/providers/usage-tracking.ts +96 -0
  1116. package/src/runtime/AGENTS.md +16 -11
  1117. package/src/runtime/__tests__/agent-wake.test.ts +122 -9
  1118. package/src/runtime/__tests__/interactive-ui.test.ts +157 -246
  1119. package/src/runtime/access-request-helper.ts +9 -20
  1120. package/src/runtime/actor-trust-resolver.ts +2 -2
  1121. package/src/runtime/agent-wake.ts +211 -68
  1122. package/src/runtime/approval-conversation-turn.ts +2 -15
  1123. package/src/runtime/approval-message-composer.ts +11 -60
  1124. package/src/runtime/assistant-event-hub.ts +541 -45
  1125. package/src/runtime/assistant-event.ts +16 -69
  1126. package/src/runtime/auth/__tests__/guard-tests.test.ts +6 -30
  1127. package/src/runtime/auth/__tests__/middleware.test.ts +10 -10
  1128. package/src/runtime/auth/__tests__/route-policy.test.ts +0 -8
  1129. package/src/runtime/auth/middleware.ts +5 -5
  1130. package/src/runtime/auth/route-policy.ts +205 -12
  1131. package/src/runtime/auth/token-service.ts +1 -111
  1132. package/src/runtime/capability-tokens.ts +89 -313
  1133. package/src/runtime/channel-approval-types.ts +1 -6
  1134. package/src/runtime/channel-approvals.ts +13 -81
  1135. package/src/runtime/channel-readiness-service.ts +2 -2
  1136. package/src/runtime/channel-reply-delivery.ts +2 -8
  1137. package/src/runtime/channel-retry-sweep.ts +20 -17
  1138. package/src/runtime/channel-verification-service.ts +3 -5
  1139. package/src/runtime/confirmation-request-guardian-bridge.ts +2 -7
  1140. package/src/runtime/gateway-client.ts +37 -378
  1141. package/src/runtime/guardian-action-grant-minter.ts +2 -3
  1142. package/src/runtime/guardian-action-message-composer.ts +11 -52
  1143. package/src/runtime/guardian-action-service.ts +19 -7
  1144. package/src/runtime/guardian-decision-types.ts +4 -65
  1145. package/src/runtime/guardian-reply-router.ts +10 -19
  1146. package/src/runtime/guardian-vellum-migration.ts +5 -64
  1147. package/src/runtime/http-errors.ts +1 -32
  1148. package/src/runtime/http-router.ts +54 -8
  1149. package/src/runtime/http-server.ts +362 -1187
  1150. package/src/runtime/http-types.ts +20 -98
  1151. package/src/runtime/interactive-ui-types.ts +145 -0
  1152. package/src/runtime/interactive-ui.ts +37 -196
  1153. package/src/runtime/invite-redemption-service.ts +1 -1
  1154. package/src/runtime/invite-redemption-templates.ts +1 -1
  1155. package/src/runtime/local-actor-identity.ts +13 -43
  1156. package/src/runtime/message-composer-types.ts +134 -0
  1157. package/src/runtime/middleware/auth.ts +0 -20
  1158. package/src/runtime/middleware/rate-limiter.ts +1 -1
  1159. package/src/runtime/middleware/request-logger.ts +5 -2
  1160. package/src/runtime/migrations/__tests__/job-registry.test.ts +346 -0
  1161. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  1162. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  1163. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  1164. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  1165. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  1166. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  1167. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  1168. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  1169. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +18 -2
  1170. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  1171. package/src/runtime/migrations/job-registry.ts +281 -0
  1172. package/src/runtime/migrations/migration-transport.ts +46 -13
  1173. package/src/runtime/migrations/migration-wizard.ts +2 -2
  1174. package/src/runtime/migrations/origin-mode.ts +40 -0
  1175. package/src/runtime/migrations/vbundle-builder.ts +133 -80
  1176. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  1177. package/src/runtime/migrations/vbundle-importer.ts +8 -8
  1178. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  1179. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -16
  1180. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  1181. package/src/runtime/migrations/vbundle-tar-stream.ts +11 -3
  1182. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  1183. package/src/runtime/nl-approval-parser.ts +16 -21
  1184. package/src/runtime/pending-interactions.ts +42 -16
  1185. package/src/runtime/routes/__tests__/acp-routes.test.ts +394 -0
  1186. package/src/runtime/routes/__tests__/backup-routes.test.ts +232 -339
  1187. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  1188. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +72 -4
  1189. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  1190. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  1191. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  1192. package/src/runtime/routes/__tests__/stt-routes.test.ts +182 -223
  1193. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +230 -0
  1194. package/src/{ipc/__tests__/task-ipc.test.ts → runtime/routes/__tests__/task-routes.test.ts} +116 -96
  1195. package/src/runtime/routes/__tests__/tts-routes.test.ts +185 -289
  1196. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  1197. package/src/runtime/routes/access-request-decision.ts +25 -50
  1198. package/src/runtime/routes/acp-routes.test.ts +368 -0
  1199. package/src/runtime/routes/acp-routes.ts +392 -170
  1200. package/src/runtime/routes/app-management-routes.ts +475 -662
  1201. package/src/runtime/routes/app-routes.ts +192 -177
  1202. package/src/runtime/routes/approval-routes.ts +163 -440
  1203. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +24 -84
  1204. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +3 -10
  1205. package/src/runtime/routes/attachment-routes.ts +409 -253
  1206. package/src/runtime/routes/audio-routes.ts +51 -18
  1207. package/src/runtime/routes/avatar-routes.ts +81 -76
  1208. package/src/runtime/routes/background-tool-routes.ts +94 -0
  1209. package/src/runtime/routes/backup-routes.ts +154 -336
  1210. package/src/runtime/routes/brain-graph-routes.ts +83 -110
  1211. package/src/runtime/routes/browser-routes.ts +127 -0
  1212. package/src/runtime/routes/btw-routes.ts +62 -106
  1213. package/src/runtime/routes/cache-routes.ts +96 -0
  1214. package/src/runtime/routes/call-routes.ts +208 -247
  1215. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +1 -1
  1216. package/src/runtime/routes/channel-delivery-routes.ts +25 -27
  1217. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  1218. package/src/runtime/routes/channel-readiness-routes.ts +79 -120
  1219. package/src/runtime/routes/channel-route-definitions.ts +62 -0
  1220. package/src/runtime/routes/channel-route-shared.ts +15 -45
  1221. package/src/runtime/routes/channel-verification-routes.ts +207 -187
  1222. package/src/runtime/routes/client-routes.ts +81 -0
  1223. package/src/runtime/routes/consolidation-routes.ts +115 -0
  1224. package/src/runtime/routes/contact-routes.ts +533 -407
  1225. package/src/runtime/routes/conversation-analysis-routes.ts +48 -49
  1226. package/src/runtime/routes/conversation-attention-routes.ts +55 -67
  1227. package/src/runtime/routes/conversation-list-routes.ts +248 -0
  1228. package/src/runtime/routes/conversation-management-routes.ts +591 -717
  1229. package/src/runtime/routes/conversation-query-routes.ts +621 -459
  1230. package/src/runtime/routes/conversation-routes.ts +396 -792
  1231. package/src/runtime/routes/conversation-starter-routes.ts +137 -108
  1232. package/src/runtime/routes/credential-prompt-routes.ts +124 -0
  1233. package/src/runtime/routes/debug-routes.ts +34 -39
  1234. package/src/runtime/routes/defer-routes.ts +230 -0
  1235. package/src/runtime/routes/diagnostics-routes.ts +79 -70
  1236. package/src/runtime/routes/documents-routes.ts +163 -117
  1237. package/src/runtime/routes/errors.ts +132 -0
  1238. package/src/runtime/routes/events-routes.ts +126 -119
  1239. package/src/runtime/routes/filing-routes.ts +80 -76
  1240. package/src/runtime/routes/global-search-routes.ts +51 -57
  1241. package/src/runtime/routes/group-routes.ts +199 -181
  1242. package/src/runtime/routes/guardian-action-routes.ts +100 -171
  1243. package/src/runtime/routes/guardian-approval-interception.ts +27 -58
  1244. package/src/runtime/routes/guardian-approval-prompt.ts +10 -21
  1245. package/src/runtime/routes/guardian-approval-reply-helpers.ts +2 -6
  1246. package/src/runtime/routes/guardian-expiry-sweep.ts +19 -36
  1247. package/src/runtime/routes/heartbeat-routes.ts +194 -209
  1248. package/src/runtime/routes/home-feed-routes.ts +85 -187
  1249. package/src/runtime/routes/home-state-routes.ts +27 -24
  1250. package/src/runtime/routes/host-bash-routes.ts +45 -54
  1251. package/src/runtime/routes/host-browser-routes.ts +44 -99
  1252. package/src/runtime/routes/host-cu-routes.ts +80 -71
  1253. package/src/runtime/routes/host-file-routes.ts +53 -62
  1254. package/src/runtime/routes/host-transfer-routes.ts +216 -0
  1255. package/src/runtime/routes/http-adapter.ts +172 -0
  1256. package/src/runtime/routes/identity-routes.ts +161 -85
  1257. package/src/runtime/routes/inbound-conversation.ts +11 -18
  1258. package/src/runtime/routes/inbound-message-handler.ts +639 -232
  1259. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +81 -226
  1260. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +2 -3
  1261. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -90
  1262. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +25 -50
  1263. package/src/runtime/routes/inbound-stages/edit-intercept.ts +7 -7
  1264. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
  1265. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +5 -6
  1266. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -24
  1267. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -10
  1268. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
  1269. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +3 -3
  1270. package/src/runtime/routes/index.ts +201 -0
  1271. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +25 -32
  1272. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +22 -31
  1273. package/src/runtime/routes/integrations/slack/channel.ts +50 -71
  1274. package/src/runtime/routes/integrations/slack/share.ts +49 -58
  1275. package/src/runtime/routes/integrations/telegram.ts +91 -74
  1276. package/src/runtime/routes/integrations/twilio.ts +163 -240
  1277. package/src/runtime/routes/integrations/vercel.ts +57 -54
  1278. package/src/runtime/routes/interface-routes.ts +43 -0
  1279. package/src/runtime/routes/internal-oauth-routes.ts +56 -0
  1280. package/src/runtime/routes/internal-twilio-routes.ts +46 -0
  1281. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  1282. package/src/runtime/routes/llm-context-normalization.ts +4 -2
  1283. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  1284. package/src/runtime/routes/log-export-routes.ts +90 -100
  1285. package/src/runtime/routes/memory-item-routes.test.ts +152 -175
  1286. package/src/runtime/routes/memory-item-routes.ts +243 -323
  1287. package/src/runtime/routes/memory-v2-routes.ts +188 -0
  1288. package/src/runtime/routes/migration-rollback-routes.ts +167 -212
  1289. package/src/runtime/routes/migration-routes.ts +1037 -377
  1290. package/src/runtime/routes/notification-routes.ts +199 -70
  1291. package/src/runtime/routes/oauth-apps.ts +254 -251
  1292. package/src/runtime/routes/oauth-providers.ts +66 -57
  1293. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +60 -120
  1294. package/src/runtime/routes/playground/__tests__/guard.test.ts +34 -54
  1295. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +107 -151
  1296. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +41 -117
  1297. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +95 -138
  1298. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +115 -217
  1299. package/src/runtime/routes/playground/__tests__/state.test.ts +41 -90
  1300. package/src/runtime/routes/playground/conversation-not-found.ts +9 -11
  1301. package/src/runtime/routes/playground/force-compact.ts +41 -54
  1302. package/src/runtime/routes/playground/guard.ts +18 -19
  1303. package/src/runtime/routes/playground/helpers.ts +103 -0
  1304. package/src/runtime/routes/playground/index.ts +15 -27
  1305. package/src/runtime/routes/playground/inject-failures.ts +48 -64
  1306. package/src/runtime/routes/playground/reset-circuit.ts +31 -57
  1307. package/src/runtime/routes/playground/seed-conversation.ts +66 -92
  1308. package/src/runtime/routes/playground/seeded-conversations.ts +60 -64
  1309. package/src/runtime/routes/playground/state.ts +23 -24
  1310. package/src/runtime/routes/profiler-routes.ts +132 -167
  1311. package/src/runtime/routes/ps-routes.ts +120 -0
  1312. package/src/runtime/routes/recording-routes.ts +189 -270
  1313. package/src/runtime/routes/rename-conversation-routes.ts +85 -0
  1314. package/src/runtime/routes/schedule-routes.ts +239 -246
  1315. package/src/runtime/routes/secret-routes.ts +305 -282
  1316. package/src/runtime/routes/secrets-deps.ts +24 -0
  1317. package/src/runtime/routes/settings-routes.ts +370 -449
  1318. package/src/runtime/routes/skills-routes.ts +417 -471
  1319. package/src/runtime/routes/stt-routes.ts +196 -206
  1320. package/src/runtime/routes/subagents-routes.ts +125 -141
  1321. package/src/runtime/routes/suggest-trust-rule-routes.ts +275 -0
  1322. package/src/runtime/routes/surface-action-routes.ts +135 -190
  1323. package/src/runtime/routes/surface-content-routes.ts +84 -118
  1324. package/src/runtime/routes/task-routes.ts +354 -0
  1325. package/src/runtime/routes/telemetry-routes.ts +33 -49
  1326. package/src/runtime/routes/trace-event-routes.ts +55 -74
  1327. package/src/runtime/routes/trust-rules-routes.ts +61 -244
  1328. package/src/runtime/routes/tts-routes.ts +187 -169
  1329. package/src/runtime/routes/types.ts +139 -0
  1330. package/src/{ipc/routes/ui-request.ts → runtime/routes/ui-request-routes.ts} +23 -17
  1331. package/src/runtime/routes/upgrade-broadcast-routes.ts +150 -198
  1332. package/src/runtime/routes/usage-routes.ts +222 -171
  1333. package/src/runtime/routes/user-routes.ts +88 -18
  1334. package/src/runtime/routes/wake-conversation-routes.ts +49 -0
  1335. package/src/{ipc/routes/watcher.ts → runtime/routes/watcher-routes.ts} +84 -39
  1336. package/src/runtime/routes/wipe-conversation-routes.ts +89 -0
  1337. package/src/runtime/routes/work-items-routes.test.ts +10 -20
  1338. package/src/runtime/routes/work-items-routes.ts +419 -437
  1339. package/src/runtime/routes/workspace-commit-routes.ts +30 -61
  1340. package/src/runtime/routes/workspace-routes.test.ts +254 -381
  1341. package/src/runtime/routes/workspace-routes.ts +238 -246
  1342. package/src/runtime/runtime-mode.ts +8 -1
  1343. package/src/runtime/services/__tests__/analyze-conversation.test.ts +82 -120
  1344. package/src/runtime/services/analyze-conversation.ts +18 -55
  1345. package/src/runtime/services/conversation-serializer.ts +179 -0
  1346. package/src/runtime/trust-context-resolver.ts +3 -2
  1347. package/src/runtime/verification-outbound-actions.ts +14 -50
  1348. package/src/runtime/verification-rate-limiter.ts +1 -1
  1349. package/src/schedule/schedule-store.ts +64 -18
  1350. package/src/schedule/scheduler.ts +101 -0
  1351. package/src/security/ces-credential-client.ts +32 -169
  1352. package/src/security/ces-rpc-credential-backend.ts +1 -1
  1353. package/src/security/credential-backend.ts +6 -6
  1354. package/src/security/oauth-completion-page.ts +1 -1
  1355. package/src/security/oauth2.ts +3 -6
  1356. package/src/security/secret-scanner.ts +14 -547
  1357. package/src/security/secure-keys.ts +31 -11
  1358. package/src/security/token-manager.ts +7 -3
  1359. package/src/sequence/analytics.ts +1 -1
  1360. package/src/sequence/guardrails.ts +3 -3
  1361. package/src/sequence/store.ts +2 -1
  1362. package/src/signals/bash.ts +1 -1
  1363. package/src/signals/cancel.ts +16 -25
  1364. package/src/signals/conversation-undo.ts +2 -27
  1365. package/src/signals/emit-event.ts +1 -2
  1366. package/src/signals/event-stream.ts +1 -1
  1367. package/src/signals/user-message.ts +108 -22
  1368. package/src/skills/catalog-cache.ts +7 -0
  1369. package/src/skills/catalog-files.ts +0 -5
  1370. package/src/skills/catalog-install.ts +29 -18
  1371. package/src/skills/category-inference.ts +0 -11
  1372. package/src/skills/clawhub.ts +4 -4
  1373. package/src/skills/inline-command-runner.ts +1 -7
  1374. package/src/skills/managed-store.ts +2 -2
  1375. package/src/skills/remote-skill-policy.ts +6 -7
  1376. package/src/subagent/index.ts +2 -6
  1377. package/src/subagent/manager.ts +94 -107
  1378. package/src/subagent/types.ts +9 -0
  1379. package/src/tasks/SPEC.md +2 -2
  1380. package/src/tasks/task-compiler.ts +1 -1
  1381. package/src/tasks/task-runner.ts +2 -22
  1382. package/src/tasks/task-store.ts +2 -29
  1383. package/src/telemetry/types.ts +6 -0
  1384. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  1385. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  1386. package/src/tools/acp/list-agents.test.ts +115 -0
  1387. package/src/tools/acp/list-agents.ts +31 -0
  1388. package/src/tools/acp/spawn.test.ts +378 -0
  1389. package/src/tools/acp/spawn.ts +142 -62
  1390. package/src/tools/acp/steer.test.ts +100 -0
  1391. package/src/tools/acp/steer.ts +38 -0
  1392. package/src/tools/background-tool-registry.ts +98 -0
  1393. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  1394. package/src/tools/browser/browser-execution.ts +38 -127
  1395. package/src/tools/browser/browser-manager.ts +1 -8
  1396. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  1397. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +1 -1
  1398. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +3 -1
  1399. package/src/tools/browser/cdp-client/factory.ts +48 -76
  1400. package/src/tools/browser/cdp-client/index.ts +1 -14
  1401. package/src/tools/browser/cdp-client/types.ts +4 -1
  1402. package/src/tools/computer-use/definitions.ts +1 -1
  1403. package/src/tools/credential-execution/make-authenticated-request.ts +2 -2
  1404. package/src/tools/credential-execution/manage-secure-command-tool.ts +1 -1
  1405. package/src/tools/credential-execution/run-authenticated-command.ts +2 -2
  1406. package/src/tools/credentials/broker-types.ts +2 -1
  1407. package/src/tools/document/editor-template.ts +1 -1
  1408. package/src/tools/execution-timeout.ts +1 -1
  1409. package/src/tools/executor.ts +53 -45
  1410. package/src/tools/host-filesystem/edit.ts +3 -2
  1411. package/src/tools/host-filesystem/read.ts +3 -2
  1412. package/src/tools/host-filesystem/transfer.test.ts +271 -0
  1413. package/src/tools/host-filesystem/transfer.ts +235 -0
  1414. package/src/tools/host-filesystem/write.ts +3 -2
  1415. package/src/tools/host-terminal/host-shell.ts +192 -13
  1416. package/src/tools/mcp/mcp-tool-factory.ts +1 -1
  1417. package/src/tools/memory/register.test.ts +161 -1
  1418. package/src/tools/memory/register.ts +19 -34
  1419. package/src/tools/network/script-proxy/index.ts +1 -10
  1420. package/src/tools/permission-checker.ts +84 -220
  1421. package/src/tools/policy-context.ts +1 -8
  1422. package/src/tools/registry.ts +16 -1
  1423. package/src/tools/shared/shell-output.ts +4 -1
  1424. package/src/tools/side-effects.ts +2 -2
  1425. package/src/tools/skills/execute.ts +1 -1
  1426. package/src/tools/skills/sandbox-runner.ts +1 -6
  1427. package/src/tools/skills/skill-tool-factory.ts +32 -0
  1428. package/src/tools/subagent/spawn.ts +35 -11
  1429. package/src/tools/terminal/safe-env.ts +10 -1
  1430. package/src/tools/terminal/shell.ts +142 -88
  1431. package/src/tools/tool-approval-handler.ts +4 -70
  1432. package/src/tools/tool-input-summary.ts +10 -0
  1433. package/src/tools/types.ts +136 -183
  1434. package/src/tools/ui-surface/definitions.ts +2 -2
  1435. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  1436. package/src/tts/provider-catalog.ts +1 -1
  1437. package/src/usage/actors.ts +2 -1
  1438. package/src/usage/attribution.ts +185 -0
  1439. package/src/usage/pricing.ts +166 -0
  1440. package/src/usage/types.ts +14 -0
  1441. package/src/util/debounce.ts +0 -21
  1442. package/src/util/errors.ts +0 -8
  1443. package/src/util/json.ts +13 -0
  1444. package/src/util/log-redact.ts +0 -1
  1445. package/src/util/logger.ts +3 -3
  1446. package/src/util/platform.ts +85 -124
  1447. package/src/util/pricing.ts +158 -8
  1448. package/src/watcher/engine.ts +42 -20
  1449. package/src/watcher/watcher-store.ts +2 -1
  1450. package/src/work-items/work-item-runner.ts +15 -42
  1451. package/src/work-items/work-item-store.ts +1 -1
  1452. package/src/workspace/git-service.ts +1 -6
  1453. package/src/workspace/migrations/006-services-config.ts +10 -1
  1454. package/src/workspace/migrations/017-seed-persona-dirs.ts +1 -1
  1455. package/src/workspace/migrations/019-scope-journal-to-guardian.ts +1 -1
  1456. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +1 -1
  1457. package/src/workspace/migrations/031-drop-user-md.ts +1 -1
  1458. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +3 -4
  1459. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  1460. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +150 -0
  1461. package/src/workspace/migrations/053-release-notes-acp-codex.ts +107 -0
  1462. package/src/workspace/migrations/054-seed-recall-callsite.ts +102 -0
  1463. package/src/workspace/migrations/055-release-notes-agentic-recall.ts +63 -0
  1464. package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +65 -0
  1465. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +98 -0
  1466. package/src/workspace/migrations/058-release-notes-acp-sessions-ui.ts +71 -0
  1467. package/src/workspace/migrations/059-move-pid-to-workspace.ts +53 -0
  1468. package/src/workspace/migrations/060-memory-v2-init.ts +37 -0
  1469. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  1470. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  1471. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  1472. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  1473. package/src/workspace/migrations/rebuild-conversation-disk-view.ts +1 -1
  1474. package/src/workspace/migrations/registry.ts +26 -0
  1475. package/src/workspace/migrations/runner.ts +2 -2
  1476. package/src/workspace/provider-commit-message-generator.ts +4 -4
  1477. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +0 -471
  1478. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +0 -436
  1479. package/src/__tests__/cli-command-risk-guard.test.ts +0 -368
  1480. package/src/__tests__/config-watcher-feature-flags.test.ts +0 -211
  1481. package/src/__tests__/conversation-approval-overrides.test.ts +0 -207
  1482. package/src/__tests__/conversation-host-access-routes.test.ts +0 -229
  1483. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +0 -226
  1484. package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +0 -167
  1485. package/src/__tests__/ephemeral-permissions.test.ts +0 -474
  1486. package/src/__tests__/extension-id-sync-guard.test.ts +0 -241
  1487. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +0 -374
  1488. package/src/__tests__/native-host-marker-sync-guard.test.ts +0 -157
  1489. package/src/__tests__/pairing-concurrent.test.ts +0 -84
  1490. package/src/__tests__/pairing-routes.test.ts +0 -181
  1491. package/src/__tests__/parser.test.ts +0 -595
  1492. package/src/__tests__/permission-checker-host-gate.test.ts +0 -488
  1493. package/src/__tests__/permission-controls-v2-flag.test.ts +0 -55
  1494. package/src/__tests__/permission-mode.test.ts +0 -89
  1495. package/src/__tests__/provider-env-vars-scope.test.ts +0 -52
  1496. package/src/__tests__/risk-classifier-parity.test.ts +0 -230
  1497. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  1498. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  1499. package/src/__tests__/secret-detection-handler.test.ts +0 -74
  1500. package/src/__tests__/secret-scanner-executor.test.ts +0 -451
  1501. package/src/__tests__/shell-identity.test.ts +0 -236
  1502. package/src/__tests__/shell-parser-fuzz.test.ts +0 -629
  1503. package/src/__tests__/shell-parser-property.test.ts +0 -936
  1504. package/src/__tests__/starter-bundle.test.ts +0 -173
  1505. package/src/__tests__/stt-catalog-parity.test.ts +0 -282
  1506. package/src/__tests__/task-runner.test.ts +0 -224
  1507. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  1508. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  1509. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -354
  1510. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  1511. package/src/__tests__/trust-store-pattern-matches.test.ts +0 -29
  1512. package/src/__tests__/trust-store.test.ts +0 -2013
  1513. package/src/__tests__/v2-consent-policy.test.ts +0 -103
  1514. package/src/browser/identifiers.ts +0 -51
  1515. package/src/cli/db.ts +0 -1
  1516. package/src/config/bundled-skills/settings/tools/avatar-get.ts +0 -40
  1517. package/src/config/bundled-skills/settings/tools/avatar-remove.ts +0 -64
  1518. package/src/config/bundled-skills/settings/tools/avatar-update.ts +0 -88
  1519. package/src/context/__tests__/microcompact.test.ts +0 -805
  1520. package/src/context/microcompact.ts +0 -443
  1521. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +0 -127
  1522. package/src/daemon/approved-devices-store.ts +0 -110
  1523. package/src/daemon/external-skills-bootstrap.ts +0 -41
  1524. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  1525. package/src/daemon/message-types/trust.ts +0 -71
  1526. package/src/daemon/pairing-store.ts +0 -229
  1527. package/src/events/tool-notification-listener.ts +0 -17
  1528. package/src/ipc/cli-server.ts +0 -252
  1529. package/src/ipc/routes/attachment.ts +0 -114
  1530. package/src/ipc/routes/browser-context.ts +0 -63
  1531. package/src/ipc/routes/browser.ts +0 -97
  1532. package/src/ipc/routes/cache.ts +0 -96
  1533. package/src/ipc/routes/get-contact.ts +0 -16
  1534. package/src/ipc/routes/index.ts +0 -35
  1535. package/src/ipc/routes/list-clients.ts +0 -31
  1536. package/src/ipc/routes/merge-contacts.ts +0 -17
  1537. package/src/ipc/routes/notification.ts +0 -133
  1538. package/src/ipc/routes/rename-conversation.ts +0 -59
  1539. package/src/ipc/routes/search-contacts.ts +0 -19
  1540. package/src/ipc/routes/task-queue.ts +0 -226
  1541. package/src/ipc/routes/task.ts +0 -173
  1542. package/src/ipc/routes/upsert-contact.ts +0 -25
  1543. package/src/ipc/routes/wake-conversation.ts +0 -19
  1544. package/src/memory/db.ts +0 -23
  1545. package/src/permissions/arg-parser.test.ts +0 -161
  1546. package/src/permissions/arg-parser.ts +0 -141
  1547. package/src/permissions/bash-risk-classifier.test.ts +0 -1620
  1548. package/src/permissions/bash-risk-classifier.ts +0 -950
  1549. package/src/permissions/command-registry.test.ts +0 -774
  1550. package/src/permissions/command-registry.ts +0 -1005
  1551. package/src/permissions/defaults.ts +0 -314
  1552. package/src/permissions/file-risk-classifier.test.ts +0 -535
  1553. package/src/permissions/file-risk-classifier.ts +0 -274
  1554. package/src/permissions/permission-mode.ts +0 -24
  1555. package/src/permissions/schedule-risk-classifier.test.ts +0 -129
  1556. package/src/permissions/schedule-risk-classifier.ts +0 -85
  1557. package/src/permissions/shell-identity.ts +0 -297
  1558. package/src/permissions/skill-risk-classifier.test.ts +0 -311
  1559. package/src/permissions/skill-risk-classifier.ts +0 -214
  1560. package/src/permissions/trust-client.ts +0 -359
  1561. package/src/permissions/trust-store-interface.ts +0 -100
  1562. package/src/permissions/trust-store.ts +0 -1330
  1563. package/src/permissions/v2-consent-policy.ts +0 -87
  1564. package/src/permissions/web-risk-classifier.test.ts +0 -170
  1565. package/src/permissions/web-risk-classifier.ts +0 -89
  1566. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +0 -715
  1567. package/src/runtime/__tests__/capability-tokens.test.ts +0 -258
  1568. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  1569. package/src/runtime/__tests__/client-registry.test.ts +0 -293
  1570. package/src/runtime/actor-refresh-token-store.ts +0 -156
  1571. package/src/runtime/actor-token-store.ts +0 -207
  1572. package/src/runtime/auth/__tests__/credential-service.test.ts +0 -264
  1573. package/src/runtime/auth/credential-service.ts +0 -352
  1574. package/src/runtime/chrome-extension-registry.ts +0 -368
  1575. package/src/runtime/client-registry.ts +0 -261
  1576. package/src/runtime/conversation-approval-overrides.ts +0 -86
  1577. package/src/runtime/routes/browser-extension-pair-routes.ts +0 -575
  1578. package/src/runtime/routes/channel-routes.ts +0 -112
  1579. package/src/runtime/routes/contact-routes.test.ts +0 -298
  1580. package/src/runtime/routes/guardian-bootstrap-routes.ts +0 -175
  1581. package/src/runtime/routes/guardian-refresh-routes.ts +0 -79
  1582. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -336
  1583. package/src/runtime/routes/invite-routes.ts +0 -280
  1584. package/src/runtime/routes/pairing-routes.ts +0 -431
  1585. package/src/runtime/routes/playground/deps.ts +0 -56
  1586. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +0 -67
  1587. package/src/runtime/services/analyze-deps-singleton.ts +0 -32
  1588. package/src/tasks/ephemeral-permissions.ts +0 -55
  1589. package/src/tools/secret-detection-handler.ts +0 -359
  1590. package/src/tools/terminal/backends/native.ts +0 -327
  1591. package/src/tools/terminal/backends/types.ts +0 -37
  1592. package/src/tools/terminal/parser.ts +0 -623
  1593. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  1594. package/src/tools/terminal/sandbox.ts +0 -40
  1595. package/src/types/qrcode.d.ts +0 -13
  1596. package/src/util/network-info.ts +0 -55
  1597. /package/node_modules/@vellumai/{ces-contracts → ces-client}/tsconfig.json +0 -0
  1598. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/__tests__/grants.test.ts +0 -0
  1599. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/error.ts +0 -0
  1600. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/grants.ts +0 -0
  1601. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/handles.ts +0 -0
  1602. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rendering.ts +0 -0
  1603. /package/node_modules/@vellumai/{ces-contracts → service-contracts}/src/rpc.ts +0 -0
@@ -1,122 +1,47 @@
1
- import { existsSync, readFileSync, statSync } from "node:fs";
1
+ import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
 
4
- import {
5
- disposeAcpSessionManager,
6
- getAcpSessionManager,
7
- setBroadcastToAllClients,
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";
4
+ import { disposeAcpSessionManager } from "../acp/index.js";
15
5
  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";
23
6
  import { getConfig } from "../config/loader.js";
24
7
  import { onContactChange } from "../contacts/contact-events.js";
25
8
  import type { CesClient } from "../credential-execution/client.js";
26
9
  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";
10
+ import { AssistantIpcServer } from "../ipc/assistant-server.js";
11
+ import { SkillIpcServer } from "../ipc/skill-server.js";
31
12
  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
- 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";
50
- import { getOrCreateConversation } from "../memory/conversation-key-store.js";
51
13
  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";
60
- import { buildAssistantEvent } from "../runtime/assistant-event.js";
61
- import { assistantEventHub } from "../runtime/assistant-event-hub.js";
62
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
14
+ import { initializeProviders } from "../providers/registry.js";
15
+ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
63
16
  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
- import { checkIngressForSecrets } from "../security/secret-ingress.js";
68
- import { redactSecrets } from "../security/secret-scanner.js";
69
17
  import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
70
- import { registerCancelCallback } from "../signals/cancel.js";
71
- import { registerConversationUndoCallback } from "../signals/conversation-undo.js";
72
- import { appendEventToStream } from "../signals/event-stream.js";
73
- import { registerUserMessageCallback } from "../signals/user-message.js";
74
18
  import { getSubagentManager } from "../subagent/index.js";
75
- import { summarizeToolInput } from "../tools/tool-input-summary.js";
76
- import { createAbortReason } from "../util/abort-reasons.js";
77
19
  import { getLogger } from "../util/logger.js";
78
20
  import {
79
21
  getAvatarImagePath,
80
- getSandboxWorkingDir,
81
22
  getWorkspacePromptPath,
82
23
  } from "../util/platform.js";
83
- import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
84
24
  import {
85
25
  AppSourceWatcher,
86
26
  setEnsureAppSourceWatcher,
87
27
  } 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";
28
+ import { getConfigWatcher } from "./config-watcher.js";
29
+ import { Conversation } from "./conversation.js";
94
30
  import { ConversationEvictor } from "./conversation-evictor.js";
95
- 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
31
  import {
101
- refreshSurfacesForApp,
102
- showStandaloneSurface,
103
- } from "./conversation-surfaces.js";
104
- import { undoLastMessage } from "./handlers/conversations.js";
32
+ allConversations,
33
+ clearConversations,
34
+ conversationEntries,
35
+ deleteConversation,
36
+ getConversationMap,
37
+ getOrCreateConversation as getOrCreateActiveConversation,
38
+ initConversationLifecycle,
39
+ setCesClientPromise,
40
+ } from "./conversation-store.js";
41
+ import { refreshSurfacesForApp } from "./conversation-surfaces.js";
105
42
  import { parseIdentityFields } from "./handlers/identity.js";
106
- import type {
107
- ConversationCreateOptions,
108
- HandlerContext,
109
- } 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";
115
- import type {
116
- ServerMessage,
117
- UserMessageAttachment,
118
- } from "./message-protocol.js";
119
- import { buildTransportHints } from "./transport-hints.js";
43
+ import type { ConversationCreateOptions } from "./handlers/shared.js";
44
+ import { setGlobalSkillIpcSender } from "./meet-host-supervisor.js";
120
45
 
121
46
  const log = getLogger("server");
122
47
 
@@ -134,181 +59,16 @@ function readPackageVersion(): string | undefined {
134
59
 
135
60
  const daemonVersion = readPackageVersion();
136
61
 
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
62
  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
63
  private sharedRequestTimestamps: number[] = [];
304
64
  private unsubscribeContactChange: (() => void) | null = null;
305
65
  private evictor: ConversationEvictor;
306
- private _hubChain: Promise<void> = Promise.resolve();
307
66
 
308
67
  // Composed subsystems
309
- private configWatcher = new ConfigWatcher();
68
+ private configWatcher = getConfigWatcher();
310
69
  private appSourceWatcher = new AppSourceWatcher();
311
- private cliIpc = new CliIpcServer();
70
+ private cliIpc = new AssistantIpcServer();
71
+ private skillIpc = new SkillIpcServer();
312
72
 
313
73
  // CES (Credential Execution Service) — process-level singleton.
314
74
  // Lifecycle is managed by startCesProcess() in lifecycle.ts; the server
@@ -320,11 +80,6 @@ export class DaemonServer {
320
80
  /** Monotonically increasing counter to detect stale client updates. */
321
81
  private cesClientGeneration = 0;
322
82
 
323
- /**
324
- * Logical assistant identifier used when publishing to the assistant-events hub.
325
- */
326
- assistantId: string = DAEMON_INTERNAL_ASSISTANT_ID;
327
-
328
83
  /**
329
84
  * Inject the CES client and process manager from the caller (lifecycle.ts).
330
85
  * Must be called before start().
@@ -352,6 +107,7 @@ export class DaemonServer {
352
107
  }
353
108
  return client;
354
109
  });
110
+ setCesClientPromise(this.cesClientPromise);
355
111
  }
356
112
  }
357
113
 
@@ -374,68 +130,22 @@ export class DaemonServer {
374
130
  this.cesClientRef = client;
375
131
  }
376
132
 
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
133
  constructor() {
432
- this.evictor = new ConversationEvictor(this.conversations);
134
+ this.evictor = new ConversationEvictor(getConversationMap());
433
135
  getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
434
- getSubagentManager().broadcastToAllClients = (msg) => this.broadcast(msg);
435
- getSubagentManager().resolveParentConversation = (id) =>
436
- this.conversations.get(id);
437
- setBroadcastToAllClients((msg) => this.broadcast(msg));
136
+
137
+ initConversationLifecycle({
138
+ evictor: this.evictor,
139
+ sharedRequestTimestamps: this.sharedRequestTimestamps,
140
+ });
141
+
438
142
  setEnsureAppSourceWatcher(() => this.appSourceWatcher.ensureStarted());
143
+ // Wire the skill IPC server into the meet-host supervisor's lazy
144
+ // dispatch path. The supervisor is constructed in
145
+ // `initializeProvidersAndTools()` (via `startMeetHost`), which can run
146
+ // before or after this DaemonServer instance, so the sender flows
147
+ // through a module-level global rather than constructor injection.
148
+ setGlobalSkillIpcSender(this.skillIpc);
439
149
  this.evictor.onEvict = (conversationId: string) => {
440
150
  getSubagentManager().abortAllForParent(conversationId);
441
151
  };
@@ -445,121 +155,6 @@ export class DaemonServer {
445
155
  (c) => c.status === "running" || c.status === "pending",
446
156
  );
447
157
  };
448
- getSubagentManager().onSubagentFinished = async (
449
- parentConversationId,
450
- message,
451
- sendToClient,
452
- notification,
453
- ) => {
454
- const parentConversation = this.conversations.get(parentConversationId);
455
- if (!parentConversation) {
456
- log.warn(
457
- { parentConversationId },
458
- "Subagent finished but parent conversation not found",
459
- );
460
- return;
461
- }
462
- const requestId = `subagent-notify-${Date.now()}`;
463
- const metadata = { subagentNotification: notification };
464
- const enqueueResult = parentConversation.enqueueMessage(
465
- message,
466
- [],
467
- sendToClient,
468
- requestId,
469
- undefined,
470
- undefined,
471
- metadata,
472
- );
473
- if (!enqueueResult.queued && !enqueueResult.rejected) {
474
- const messageId = await parentConversation.persistUserMessage(
475
- message,
476
- [],
477
- undefined,
478
- metadata,
479
- );
480
- parentConversation
481
- .runAgentLoop(message, messageId, sendToClient)
482
- .catch((err) => {
483
- log.error(
484
- { parentConversationId, err },
485
- "Failed to process subagent notification in parent",
486
- );
487
- });
488
- }
489
- };
490
- getAcpSessionManager().onAcpSessionFinished = async (
491
- parentConversationId,
492
- message,
493
- sendToClient,
494
- ) => {
495
- const parentConversation = this.conversations.get(parentConversationId);
496
- if (!parentConversation) {
497
- log.warn(
498
- { parentConversationId },
499
- "ACP agent finished but parent conversation not found",
500
- );
501
- return;
502
- }
503
- const requestId = `acp-notify-${Date.now()}`;
504
- const enqueueResult = parentConversation.enqueueMessage(
505
- message,
506
- [],
507
- sendToClient,
508
- requestId,
509
- );
510
- if (!enqueueResult.queued && !enqueueResult.rejected) {
511
- const messageId = await parentConversation.persistUserMessage(
512
- message,
513
- [],
514
- );
515
- parentConversation
516
- .runAgentLoop(message, messageId, sendToClient)
517
- .catch((err: unknown) => {
518
- log.error(
519
- { parentConversationId, err },
520
- "Failed to process ACP notification in parent",
521
- );
522
- });
523
- }
524
- };
525
- }
526
-
527
- // ── Broadcast / Event publishing ──────────────────────────────────
528
-
529
- /**
530
- * Publish `msg` as an `AssistantEvent` to the process-level hub.
531
- * Publications are serialized via a promise chain so subscribers
532
- * always observe events in send order.
533
- */
534
- private publishAssistantEvent(
535
- msg: ServerMessage,
536
- conversationId?: string,
537
- ): void {
538
- const id = this.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID;
539
- const event = buildAssistantEvent(id, msg, conversationId);
540
- this._hubChain = this._hubChain
541
- .then(() => assistantEventHub.publish(event))
542
- .catch((err: unknown) => {
543
- log.warn(
544
- { err },
545
- "assistant-events hub subscriber threw during broadcast",
546
- );
547
- });
548
-
549
- // Dual-write to file-based stream for cross-process consumers.
550
- // No-op when no subscriber files exist for this conversation.
551
- if (conversationId) {
552
- try {
553
- appendEventToStream(conversationId, event);
554
- } catch {
555
- // Best-effort; file I/O failures must not block the hub chain.
556
- }
557
- }
558
- }
559
-
560
- broadcast(msg: ServerMessage): void {
561
- const conversationId = extractConversationId(msg);
562
- this.publishAssistantEvent(msg, conversationId);
563
158
  }
564
159
 
565
160
  private broadcastIdentityChanged(): void {
@@ -569,7 +164,7 @@ export class DaemonServer {
569
164
  ? readFileSync(identityPath, "utf-8")
570
165
  : "";
571
166
  const fields = parseIdentityFields(content);
572
- this.broadcast({
167
+ broadcastMessage({
573
168
  type: "identity_changed",
574
169
  name: fields.name,
575
170
  role: fields.role,
@@ -604,19 +199,15 @@ export class DaemonServer {
604
199
  }
605
200
 
606
201
  private broadcastConfigChanged(): void {
607
- this.broadcast({ type: "config_changed" });
202
+ broadcastMessage({ type: "config_changed" });
608
203
  }
609
204
 
610
205
  private broadcastSoundsConfigUpdated(): void {
611
- this.broadcast({ type: "sounds_config_updated" });
612
- }
613
-
614
- private broadcastFeatureFlagsChanged(): void {
615
- this.broadcast({ type: "feature_flags_changed" });
206
+ broadcastMessage({ type: "sounds_config_updated" });
616
207
  }
617
208
 
618
209
  private broadcastAvatarUpdated(): void {
619
- this.broadcast({
210
+ broadcastMessage({
620
211
  type: "avatar_updated",
621
212
  avatarPath: getAvatarImagePath(),
622
213
  });
@@ -631,10 +222,10 @@ export class DaemonServer {
631
222
  if (!app) return;
632
223
 
633
224
  const doRefresh = () => {
634
- for (const conversation of this.conversations.values()) {
225
+ for (const conversation of allConversations()) {
635
226
  refreshSurfacesForApp(conversation, appId, { fileChange: true });
636
227
  }
637
- this.broadcast({ type: "app_files_changed", appId });
228
+ broadcastMessage({ type: "app_files_changed", appId });
638
229
  void updatePublishedAppDeployment(appId);
639
230
  };
640
231
 
@@ -669,257 +260,13 @@ export class DaemonServer {
669
260
 
670
261
  this.evictor.start();
671
262
 
672
- registerDaemonCallbacks({
673
- getOrCreateConversation: (conversationId) =>
674
- this.getOrCreateConversation(conversationId),
675
- broadcast: (msg) => this.broadcast(msg),
676
- });
677
-
678
- registerCancelCallback((conversationId) => {
679
- const conversation = this.conversations.get(conversationId);
680
- if (!conversation) return false;
681
- this.evictor.touch(conversationId);
682
- conversation.abort(
683
- createAbortReason(
684
- "signal_cancel",
685
- "registerCancelCallback",
686
- conversationId,
687
- ),
688
- );
689
- getSubagentManager().abortAllForParent(conversationId);
690
- return true;
691
- });
692
-
693
- registerConversationUndoCallback((conversationId) =>
694
- undoLastMessage(conversationId, this.handlerContext()),
695
- );
696
-
697
- registerUserMessageCallback(async (params) => {
698
- // Block messages containing known-format secrets before persistence
699
- if (!params.bypassSecretCheck) {
700
- const ingressResult = checkIngressForSecrets(params.content);
701
- if (ingressResult.blocked) {
702
- return {
703
- accepted: false,
704
- error: "secret_blocked" as const,
705
- message: ingressResult.userNotice,
706
- };
707
- }
708
- }
709
-
710
- const { conversationId } = getOrCreateConversation(
711
- params.conversationKey,
712
- );
713
- const conversation = await this.getOrCreateConversation(conversationId);
714
-
715
- // Register file-backed attachments so they flow through the send
716
- // pipeline as images the LLM can see directly.
717
- const attachmentIds: string[] = [];
718
- const resolvedAttachments: UserMessageAttachment[] = [];
719
- if (params.attachments && params.attachments.length > 0) {
720
- for (const a of params.attachments) {
721
- try {
722
- const validation = attachmentsStore.validateAttachmentUpload(
723
- a.filename,
724
- a.mimeType,
725
- );
726
- if (!validation.ok) {
727
- log.warn(
728
- { error: validation.error, path: a.path },
729
- "Signal attachment rejected by validation",
730
- );
731
- continue;
732
- }
733
- const size = statSync(a.path).size;
734
- const stored = attachmentsStore.uploadFileBackedAttachment(
735
- a.filename,
736
- a.mimeType,
737
- a.path,
738
- size,
739
- );
740
- attachmentIds.push(stored.id);
741
- resolvedAttachments.push({
742
- id: stored.id,
743
- filename: a.filename,
744
- mimeType: a.mimeType,
745
- data: "",
746
- filePath: a.path,
747
- });
748
- } catch (err) {
749
- log.warn(
750
- { err, path: a.path },
751
- "Failed to register signal attachment",
752
- );
753
- }
754
- }
755
- }
756
-
757
- // Build a hub-publishing sender so events reach SSE clients.
758
- const hubSender = (msg: ServerMessage) => {
759
- const msgConversationId =
760
- "conversationId" in msg &&
761
- typeof (msg as { conversationId?: unknown }).conversationId ===
762
- "string"
763
- ? (msg as { conversationId: string }).conversationId
764
- : undefined;
765
- this.publishAssistantEvent(msg, msgConversationId ?? conversationId);
766
- };
263
+ await this.cliIpc.start();
767
264
 
768
- if (conversation.isProcessing()) {
769
- // Hydrate file data now the queue path won't re-read from
770
- // the attachment store, so base64 content must be inline.
771
- for (let i = resolvedAttachments.length - 1; i >= 0; i--) {
772
- const att = resolvedAttachments[i];
773
- if (att.filePath && !att.data) {
774
- try {
775
- att.data = readFileSync(att.filePath).toString("base64");
776
- } catch (err) {
777
- log.warn(
778
- { err, path: att.filePath },
779
- "Failed to read queued signal attachment, skipping",
780
- );
781
- resolvedAttachments.splice(i, 1);
782
- }
783
- }
784
- }
785
- const requestId = crypto.randomUUID();
786
- const resolvedChannel = resolveTurnChannel(params.sourceChannel);
787
- const resolvedInterface = resolveTurnInterface(params.sourceInterface);
788
- const result = conversation.enqueueMessage(
789
- params.content,
790
- resolvedAttachments,
791
- hubSender,
792
- requestId,
793
- undefined,
794
- undefined,
795
- {
796
- userMessageChannel: resolvedChannel,
797
- assistantMessageChannel: resolvedChannel,
798
- userMessageInterface: resolvedInterface,
799
- assistantMessageInterface: resolvedInterface,
800
- },
801
- );
802
- return { accepted: !result.rejected };
803
- }
804
- await this.persistAndProcessMessage(
805
- conversationId,
806
- params.content,
807
- attachmentIds.length > 0 ? attachmentIds : undefined,
808
- { onEvent: hubSender },
809
- params.sourceChannel,
810
- params.sourceInterface,
811
- );
812
- return { accepted: true };
813
- });
814
-
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
- }
867
-
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();
897
-
898
- // Wire the launchConversation helper to daemon-side state so
899
- // handleSurfaceAction can spawn conversations through it.
900
- registerLaunchConversationDeps({
901
- getOrCreateConversation: (id, options) =>
902
- this.getOrCreateConversation(id, options),
903
- persistAndProcessMessage: (
904
- conversationId,
905
- content,
906
- attachmentIds,
907
- options,
908
- sourceChannel,
909
- sourceInterface,
910
- ) =>
911
- this.persistAndProcessMessage(
912
- conversationId,
913
- content,
914
- attachmentIds,
915
- options,
916
- sourceChannel,
917
- sourceInterface,
918
- ),
919
- publishAssistantEvent: (msg, conversationId) =>
920
- this.publishAssistantEvent(msg, conversationId),
921
- getAssistantId: () => this.assistantId,
922
- });
265
+ // Start the skill IPC server. First-party skill processes connect to this
266
+ // socket to access host capabilities (host.log, host.config.*,
267
+ // host.events.*, host.registries.*). Route registry is populated by
268
+ // subsequent PRs in the skill-isolation plan.
269
+ await this.skillIpc.start();
923
270
 
924
271
  this.configWatcher.start(
925
272
  () => this.evictConversationsForReload(),
@@ -927,7 +274,6 @@ export class DaemonServer {
927
274
  () => this.broadcastSoundsConfigUpdated(),
928
275
  () => this.broadcastAvatarUpdated(),
929
276
  () => this.broadcastConfigChanged(),
930
- () => this.broadcastFeatureFlagsChanged(),
931
277
  );
932
278
 
933
279
  this.syncIdentityToPlatform();
@@ -936,7 +282,7 @@ export class DaemonServer {
936
282
 
937
283
  // Broadcast contacts_changed to all clients when any contact mutation occurs.
938
284
  this.unsubscribeContactChange = onContactChange(() => {
939
- this.broadcast({ type: "contacts_changed" });
285
+ broadcastMessage({ type: "contacts_changed" });
940
286
  });
941
287
 
942
288
  log.info("DaemonServer started (HTTP-only mode)");
@@ -949,15 +295,16 @@ export class DaemonServer {
949
295
  this.configWatcher.stop();
950
296
  this.appSourceWatcher.stop();
951
297
  this.cliIpc.stop();
298
+ this.skillIpc.stop();
952
299
  if (this.unsubscribeContactChange) {
953
300
  this.unsubscribeContactChange();
954
301
  this.unsubscribeContactChange = null;
955
302
  }
956
303
 
957
- for (const conversation of this.conversations.values()) {
304
+ for (const conversation of allConversations()) {
958
305
  conversation.dispose();
959
306
  }
960
- this.conversations.clear();
307
+ clearConversations();
961
308
 
962
309
  // Abort any in-flight CES initialization so it fails fast instead of
963
310
  // blocking shutdown for up to ~15s (socket connect + handshake timeouts).
@@ -982,6 +329,7 @@ export class DaemonServer {
982
329
  if (this.cesClientPromise) {
983
330
  await this.cesClientPromise.catch(() => undefined);
984
331
  this.cesClientPromise = undefined;
332
+ setCesClientPromise(undefined);
985
333
  }
986
334
  if (this.cesProcessManager) {
987
335
  this.cesProcessManager = undefined;
@@ -993,49 +341,20 @@ export class DaemonServer {
993
341
  // ── Conversation management ──────────────────────────────────────────────
994
342
 
995
343
  broadcastStatus(): void {
996
- this.broadcast({
344
+ broadcastMessage({
997
345
  type: "assistant_status",
998
346
  version: daemonVersion,
999
347
  keyFingerprint: getSigningKeyFingerprint(),
1000
348
  });
1001
349
  }
1002
350
 
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
351
  private evictConversationsForReload(): void {
1033
352
  const subagentManager = getSubagentManager();
1034
- for (const [id, conversation] of this.conversations) {
353
+ for (const [id, conversation] of conversationEntries()) {
1035
354
  if (!conversation.isProcessing()) {
1036
355
  subagentManager.abortAllForParent(id);
1037
356
  conversation.dispose();
1038
- this.conversations.delete(id);
357
+ deleteConversation(id);
1039
358
  this.evictor.remove(id);
1040
359
  } else {
1041
360
  conversation.markStale();
@@ -1065,687 +384,6 @@ export class DaemonServer {
1065
384
  this.evictConversationsForReload();
1066
385
  }
1067
386
 
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
- // ── Handler context ────────────────────────────────────────────────
1202
-
1203
- private handlerContext(): HandlerContext {
1204
- return {
1205
- conversations: this.conversations,
1206
- sharedRequestTimestamps: this.sharedRequestTimestamps,
1207
- debounceTimers: this.configWatcher.timers,
1208
- suppressConfigReload: this.configWatcher.suppressConfigReload,
1209
- setSuppressConfigReload: (value: boolean) => {
1210
- this.configWatcher.suppressConfigReload = value;
1211
- },
1212
- updateConfigFingerprint: () => {
1213
- this.configWatcher.updateFingerprint();
1214
- },
1215
- send: (msg) => this.broadcast(msg),
1216
- broadcast: (msg) => this.broadcast(msg),
1217
- clearAllConversations: () => this.clearAllConversations(),
1218
- getOrCreateConversation: (id, options?) =>
1219
- this.getOrCreateConversation(id, options),
1220
- 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
- };
1237
- }
1238
-
1239
- // ── HTTP message processing ─────────────────────────────────────────
1240
-
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
- async persistAndProcessMessage(
1411
- conversationId: string,
1412
- content: string,
1413
- attachmentIds?: string[],
1414
- options?: ConversationCreateOptions,
1415
- sourceChannel?: string,
1416
- sourceInterface?: string,
1417
- ): Promise<{ messageId: string }> {
1418
- const { conversation, attachments } =
1419
- await this.prepareConversationForMessage(
1420
- conversationId,
1421
- content,
1422
- attachmentIds,
1423
- options,
1424
- sourceChannel,
1425
- sourceInterface,
1426
- );
1427
-
1428
- const requestId = crypto.randomUUID();
1429
- const messageId = await conversation.persistUserMessage(
1430
- content,
1431
- attachments,
1432
- requestId,
1433
- );
1434
-
1435
- // Register pending interactions so channel approval interception can
1436
- // find the conversation by requestId when confirmation/secret events fire.
1437
- const registrar = makePendingInteractionRegistrar(
1438
- conversation,
1439
- conversationId,
1440
- );
1441
- const onEvent = options?.onEvent
1442
- ? (msg: ServerMessage) => {
1443
- registrar(msg);
1444
- try {
1445
- options.onEvent!(msg);
1446
- } catch (err) {
1447
- log.error(
1448
- { err, conversationId },
1449
- "onEvent callback failed; continuing agent loop",
1450
- );
1451
- }
1452
- }
1453
- : registrar;
1454
- // Non-interactive interfaces that still have a connected client capable
1455
- // of handling host_browser_request events (e.g. chrome-extension) need
1456
- // their hostBrowserProxy explicitly marked connected. The proxy
1457
- // constructor defaults clientConnected = false, so without an explicit
1458
- // sender update the chrome-extension proxy would be created and
1459
- // immediately unavailable. We do NOT call updateClient(onEvent, false)
1460
- // for that case, because flipping hasNoClient false would also enable
1461
- // host_bash/host_file/host_cu tool gating for an interface that can't
1462
- // service them. Instead, provision just the browser proxy's sender.
1463
- const persistInterfaceCtx = conversation.getTurnInterfaceContext();
1464
- const persistInterface = persistInterfaceCtx?.userMessageInterface;
1465
- if (options?.isInteractive === true) {
1466
- conversation.updateClient(onEvent, false);
1467
- } else if (
1468
- persistInterface &&
1469
- !supportsHostProxy(persistInterface) &&
1470
- supportsHostProxy(persistInterface, "host_browser")
1471
- ) {
1472
- conversation.hostBrowserProxy?.updateSender(onEvent, true);
1473
- }
1474
-
1475
- conversation
1476
- .runAgentLoop(content, messageId, onEvent, {
1477
- isInteractive: options?.isInteractive ?? false,
1478
- isUserMessage: true,
1479
- ...(options?.callSite ? { callSite: options.callSite } : {}),
1480
- })
1481
- .finally(() => {
1482
- if (
1483
- options?.isInteractive === true &&
1484
- conversation.getCurrentSender() === onEvent
1485
- ) {
1486
- conversation.updateClient(() => {}, true);
1487
- }
1488
- })
1489
- .catch((err) => {
1490
- log.error({ err, conversationId }, "Background agent loop failed");
1491
- });
1492
-
1493
- return { messageId };
1494
- }
1495
-
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
387
  /**
1750
388
  * Expose conversation lookup for the POST /v1/messages handler.
1751
389
  * The handler manages busy-state checking and queueing itself.
@@ -1754,288 +392,6 @@ export class DaemonServer {
1754
392
  conversationId: string,
1755
393
  options?: ConversationCreateOptions,
1756
394
  ): Promise<Conversation> {
1757
- return this.getOrCreateConversation(conversationId, options);
395
+ return getOrCreateActiveConversation(conversationId, options);
1758
396
  }
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;
1795
- }
1796
-
1797
- /**
1798
- * Expose the handler context for use by conversation management HTTP routes.
1799
- * The context is built on-the-fly so it always reflects the current server state.
1800
- */
1801
- getHandlerContext(): HandlerContext {
1802
- return this.handlerContext();
1803
- }
1804
- }
1805
-
1806
- /** Extract conversationId from a ServerMessage if present. */
1807
- function extractConversationId(msg: ServerMessage): string | undefined {
1808
- const record = msg as unknown as Record<string, unknown>;
1809
- if ("conversationId" in msg && typeof record.conversationId === "string") {
1810
- return record.conversationId as string;
1811
- }
1812
- return undefined;
1813
- }
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
397
  }