@vellumai/assistant 0.7.1 → 0.7.3

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 (739) hide show
  1. package/ARCHITECTURE.md +48 -50
  2. package/Dockerfile +1 -0
  3. package/README.md +1 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
  5. package/bun.lock +26 -26
  6. package/docs/architecture/memory.md +5 -2
  7. package/docs/architecture/security.md +20 -0
  8. package/docs/plugins.md +7 -9
  9. package/knip.json +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  11. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
  12. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  13. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  15. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  16. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  17. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  18. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  19. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  20. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  21. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  22. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  23. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  24. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  25. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  26. package/openapi.yaml +1020 -40
  27. package/package.json +6 -3
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  29. package/src/__tests__/app-bundler.test.ts +170 -1
  30. package/src/__tests__/app-control-flow.test.ts +384 -0
  31. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  32. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  33. package/src/__tests__/app-executors.test.ts +30 -43
  34. package/src/__tests__/approval-routes-http.test.ts +23 -6
  35. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  36. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +157 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
  39. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  40. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  41. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  42. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  43. package/src/__tests__/btw-routes.test.ts +13 -4
  44. package/src/__tests__/call-controller.test.ts +49 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  46. package/src/__tests__/call-domain.test.ts +0 -2
  47. package/src/__tests__/call-routes-http.test.ts +0 -2
  48. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  49. package/src/__tests__/channel-readiness-service.test.ts +62 -2
  50. package/src/__tests__/checker.test.ts +3 -4
  51. package/src/__tests__/config-loader-backfill.test.ts +461 -147
  52. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  53. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  54. package/src/__tests__/config-schema.test.ts +1 -0
  55. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  56. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
  57. package/src/__tests__/config-watcher.test.ts +142 -71
  58. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  59. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  60. package/src/__tests__/context-search-fanout.test.ts +0 -1
  61. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  62. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  63. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  64. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  65. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  66. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  67. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  68. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  70. package/src/__tests__/conversation-error.test.ts +150 -3
  71. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  72. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  74. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  80. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  81. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  82. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  83. package/src/__tests__/conversation-store.test.ts +0 -18
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  85. package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
  86. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  87. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  88. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  89. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  90. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  91. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  92. package/src/__tests__/credentials-cli.test.ts +12 -12
  93. package/src/__tests__/cu-unified-flow.test.ts +351 -23
  94. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  95. package/src/__tests__/date-context.test.ts +164 -2
  96. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  97. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  98. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  99. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  100. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  101. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  102. package/src/__tests__/disk-usage.test.ts +150 -0
  103. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  104. package/src/__tests__/events-client-registration.test.ts +52 -0
  105. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  106. package/src/__tests__/file-write-tool.test.ts +4 -10
  107. package/src/__tests__/filing-service.test.ts +3 -4
  108. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  110. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  112. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  113. package/src/__tests__/heartbeat-service.test.ts +968 -2
  114. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  115. package/src/__tests__/host-app-control-proxy.test.ts +772 -0
  116. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +439 -47
  118. package/src/__tests__/host-bash-routes.test.ts +459 -0
  119. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  120. package/src/__tests__/host-browser-routes.test.ts +39 -13
  121. package/src/__tests__/host-cu-proxy.test.ts +248 -52
  122. package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
  123. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  124. package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
  125. package/src/__tests__/host-file-proxy.test.ts +301 -45
  126. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  127. package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
  128. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  129. package/src/__tests__/host-proxy-base.test.ts +312 -0
  130. package/src/__tests__/host-shell-tool.test.ts +22 -4
  131. package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
  132. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  133. package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
  134. package/src/__tests__/http-user-message-parity.test.ts +108 -1
  135. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  136. package/src/__tests__/identity-routes.test.ts +103 -1
  137. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  138. package/src/__tests__/injector-chain.test.ts +18 -6
  139. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  140. package/src/__tests__/inline-command-runner.test.ts +0 -1
  141. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  142. package/src/__tests__/integration-status.test.ts +85 -5
  143. package/src/__tests__/intent-routing.test.ts +0 -1
  144. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  145. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  146. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  147. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  148. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  149. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  150. package/src/__tests__/mcp-cli.test.ts +338 -2
  151. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  153. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  155. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  156. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  157. package/src/__tests__/oauth-cli.test.ts +0 -2
  158. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  160. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  161. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  162. package/src/__tests__/openai-provider.test.ts +45 -8
  163. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  164. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  165. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  166. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  167. package/src/__tests__/platform.test.ts +2 -1
  168. package/src/__tests__/playbook-execution.test.ts +0 -43
  169. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  170. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
  171. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  172. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  173. package/src/__tests__/provider-tool-name.test.ts +23 -0
  174. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  175. package/src/__tests__/relay-server.test.ts +15 -4
  176. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  177. package/src/__tests__/retry-backoff.test.ts +87 -0
  178. package/src/__tests__/runtime-events-sse.test.ts +2 -2
  179. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  180. package/src/__tests__/schedule-retry.test.ts +715 -0
  181. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  182. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  183. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  184. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  185. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  186. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  187. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  188. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  189. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  190. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  191. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  192. package/src/__tests__/slack-channel-config.test.ts +9 -14
  193. package/src/__tests__/suggestion-routes.test.ts +46 -0
  194. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  195. package/src/__tests__/system-prompt.test.ts +0 -1
  196. package/src/__tests__/telegram-config.test.ts +0 -1
  197. package/src/__tests__/test-preload.ts +8 -0
  198. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  199. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  200. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  201. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  202. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  203. package/src/__tests__/tool-executor.test.ts +0 -1
  204. package/src/__tests__/twilio-config.test.ts +3 -16
  205. package/src/__tests__/twilio-routes.test.ts +3 -5
  206. package/src/__tests__/twilio-validation.test.ts +93 -0
  207. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  208. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  209. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  210. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  211. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  212. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  213. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  214. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  215. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  216. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  217. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  218. package/src/approvals/guardian-decision-primitive.ts +13 -0
  219. package/src/approvals/guardian-request-resolvers.ts +16 -17
  220. package/src/backup/__tests__/paths.test.ts +0 -22
  221. package/src/backup/__tests__/restore.test.ts +51 -151
  222. package/src/backup/paths.ts +2 -18
  223. package/src/backup/restore.ts +107 -231
  224. package/src/backup/snapshot-lock.ts +2 -27
  225. package/src/bundler/app-bundler.ts +51 -3
  226. package/src/bundler/compiler-tools.ts +3 -2
  227. package/src/calls/call-conversation-messages.ts +46 -10
  228. package/src/calls/relay-server.ts +4 -44
  229. package/src/calls/twilio-config.ts +2 -17
  230. package/src/calls/twilio-rest.ts +33 -105
  231. package/src/calls/twilio-routes.ts +11 -12
  232. package/src/channels/types.ts +8 -7
  233. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  234. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  235. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  236. package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
  237. package/src/cli/commands/backup.ts +6 -331
  238. package/src/cli/commands/bash.ts +35 -108
  239. package/src/cli/commands/clients.ts +36 -37
  240. package/src/cli/commands/contacts.ts +137 -25
  241. package/src/cli/commands/conversations.ts +2 -5
  242. package/src/cli/commands/credentials.ts +71 -7
  243. package/src/cli/commands/domain.ts +66 -15
  244. package/src/cli/commands/gateway.ts +183 -0
  245. package/src/cli/commands/keys.ts +9 -6
  246. package/src/cli/commands/mcp.ts +116 -156
  247. package/src/cli/commands/memory-v2.ts +303 -7
  248. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  249. package/src/cli/commands/oauth/connect.ts +127 -1
  250. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
  251. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
  252. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
  253. package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
  254. package/src/cli/commands/platform/disconnect.ts +5 -4
  255. package/src/cli/commands/platform/index.ts +16 -25
  256. package/src/cli/commands/status.ts +57 -0
  257. package/src/cli/lib/daemon-credential-client.ts +110 -28
  258. package/src/cli/program.ts +6 -2
  259. package/src/config/assistant-feature-flags.ts +79 -12
  260. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  261. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  262. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  263. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  264. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  265. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  266. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  267. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  268. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  269. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  270. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  271. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  272. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  273. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  274. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  275. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  276. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  277. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  278. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  279. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  280. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  281. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  282. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  283. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  284. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  285. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  286. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  287. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
  288. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  289. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  290. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  291. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  292. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  293. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  294. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  295. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  296. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  297. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  298. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  299. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  300. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  301. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  302. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  303. package/src/config/bundled-tool-registry.ts +21 -0
  304. package/src/config/env-registry.ts +0 -2
  305. package/src/config/env.ts +19 -20
  306. package/src/config/feature-flag-registry.json +47 -135
  307. package/src/config/loader.ts +197 -104
  308. package/src/config/sanitize-for-transfer.ts +2 -0
  309. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  310. package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
  311. package/src/config/schemas/call-site-catalog.ts +14 -0
  312. package/src/config/schemas/calls.ts +0 -9
  313. package/src/config/schemas/channels.ts +0 -5
  314. package/src/config/schemas/heartbeat.ts +64 -1
  315. package/src/config/schemas/ingress.ts +10 -6
  316. package/src/config/schemas/llm.ts +7 -10
  317. package/src/config/schemas/memory-lifecycle.ts +90 -24
  318. package/src/config/schemas/memory-v2.ts +121 -13
  319. package/src/config/schemas/platform.ts +49 -3
  320. package/src/config/schemas/services.ts +29 -15
  321. package/src/config/schemas/skills.ts +0 -6
  322. package/src/config/seed-inference-profiles.ts +230 -33
  323. package/src/contacts/contact-store.ts +0 -55
  324. package/src/contacts/contacts-write.ts +0 -27
  325. package/src/context/window-manager.ts +1 -2
  326. package/src/credential-execution/feature-gates.ts +10 -10
  327. package/src/credential-execution/process-manager.ts +12 -41
  328. package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
  329. package/src/daemon/assistant-attachments.ts +4 -4
  330. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  331. package/src/daemon/config-watcher.ts +89 -60
  332. package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
  333. package/src/daemon/conversation-agent-loop.ts +202 -61
  334. package/src/daemon/conversation-error.ts +87 -15
  335. package/src/daemon/conversation-lifecycle.ts +9 -4
  336. package/src/daemon/conversation-process.ts +24 -11
  337. package/src/daemon/conversation-runtime-assembly.ts +28 -2
  338. package/src/daemon/conversation-store.ts +2 -2
  339. package/src/daemon/conversation-surfaces.ts +305 -4
  340. package/src/daemon/conversation-tool-setup.ts +66 -62
  341. package/src/daemon/conversation.ts +38 -24
  342. package/src/daemon/date-context.ts +71 -22
  343. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  344. package/src/daemon/disk-pressure-guard.ts +343 -0
  345. package/src/daemon/disk-pressure-policy.ts +163 -0
  346. package/src/daemon/doordash-steps.ts +1 -1
  347. package/src/daemon/handlers/shared.ts +4 -2
  348. package/src/daemon/handlers/skills.ts +3 -4
  349. package/src/daemon/host-app-control-proxy.ts +389 -0
  350. package/src/daemon/host-bash-proxy.ts +117 -82
  351. package/src/daemon/host-browser-proxy.ts +67 -82
  352. package/src/daemon/host-cu-proxy.ts +127 -86
  353. package/src/daemon/host-file-proxy.ts +129 -69
  354. package/src/daemon/host-proxy-base.ts +294 -0
  355. package/src/daemon/host-proxy-preactivation.ts +82 -0
  356. package/src/daemon/host-transfer-proxy.ts +338 -129
  357. package/src/daemon/lifecycle.ts +194 -145
  358. package/src/daemon/meet-host-supervisor.ts +4 -4
  359. package/src/daemon/meet-manifest-loader.ts +0 -1
  360. package/src/daemon/memory-v2-startup.ts +14 -4
  361. package/src/daemon/message-protocol.ts +6 -8
  362. package/src/daemon/message-types/contacts.ts +23 -1
  363. package/src/daemon/message-types/conversations.ts +15 -8
  364. package/src/daemon/message-types/disk-pressure.ts +9 -0
  365. package/src/daemon/message-types/host-app-control.ts +150 -0
  366. package/src/daemon/message-types/host-bash.ts +4 -0
  367. package/src/daemon/message-types/host-cu.ts +2 -0
  368. package/src/daemon/message-types/host-file.ts +4 -0
  369. package/src/daemon/message-types/host-transfer.ts +3 -0
  370. package/src/daemon/message-types/messages.ts +3 -0
  371. package/src/daemon/message-types/schedules.ts +8 -3
  372. package/src/daemon/message-types/skills.ts +2 -2
  373. package/src/daemon/process-message.ts +18 -1
  374. package/src/daemon/profiler-run-store.ts +5 -5
  375. package/src/daemon/shutdown-handlers.ts +0 -3
  376. package/src/daemon/tool-setup-types.ts +51 -0
  377. package/src/daemon/tool-side-effects.ts +1 -1
  378. package/src/documents/document-store.ts +85 -0
  379. package/src/events/tool-audit-listener.ts +2 -1
  380. package/src/filing/filing-service.ts +30 -5
  381. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
  382. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
  383. package/src/heartbeat/heartbeat-run-store.ts +249 -0
  384. package/src/heartbeat/heartbeat-service.ts +459 -54
  385. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  386. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  387. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  388. package/src/home/feed-scheduler.ts +18 -0
  389. package/src/home/post-connect-feed.ts +68 -0
  390. package/src/home/relationship-state-writer.ts +17 -92
  391. package/src/home/suggested-prompts.ts +46 -10
  392. package/src/inbound/platform-callback-registration.ts +8 -15
  393. package/src/inbound/public-ingress-urls.ts +32 -34
  394. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  395. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  396. package/src/ipc/assistant-server.ts +70 -3
  397. package/src/ipc/cli-client.ts +32 -1
  398. package/src/ipc/gateway-client.ts +37 -3
  399. package/src/live-voice/live-voice-archive.ts +4 -4
  400. package/src/live-voice/live-voice-metrics.ts +10 -10
  401. package/src/live-voice/protocol.ts +5 -7
  402. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  403. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  404. package/src/mcp/mcp-auth-state.ts +133 -0
  405. package/src/mcp/mcp-oauth-provider.ts +19 -0
  406. package/src/media/image-service.ts +1 -7
  407. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  408. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  409. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  412. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  413. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  414. package/src/memory/admin.ts +5 -9
  415. package/src/memory/anisotropy.test.ts +247 -0
  416. package/src/memory/anisotropy.ts +443 -0
  417. package/src/memory/auto-analysis-constants.ts +17 -0
  418. package/src/memory/auto-analysis-guard.ts +5 -15
  419. package/src/memory/canonical-guardian-store.ts +7 -7
  420. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  421. package/src/memory/context-search/agent-protocol.ts +6 -6
  422. package/src/memory/context-search/agent-runner.ts +51 -9
  423. package/src/memory/context-search/sources/conversations.ts +2 -11
  424. package/src/memory/context-search/sources/memory-v2.ts +22 -9
  425. package/src/memory/context-search/sources/memory.ts +0 -1
  426. package/src/memory/context-search/types.ts +0 -1
  427. package/src/memory/conversation-crud.ts +5 -13
  428. package/src/memory/conversation-key-store.ts +2 -15
  429. package/src/memory/db-init.ts +6 -0
  430. package/src/memory/embedding-backend.ts +9 -21
  431. package/src/memory/embedding-runtime-manager.ts +119 -5
  432. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
  433. package/src/memory/graph/conversation-graph-memory.ts +43 -78
  434. package/src/memory/graph/extraction.ts +1 -3
  435. package/src/memory/graph/graph-search.test.ts +10 -67
  436. package/src/memory/graph/graph-search.ts +9 -20
  437. package/src/memory/graph/retriever.test.ts +6 -0
  438. package/src/memory/graph/retriever.ts +34 -10
  439. package/src/memory/graph/tools.ts +1 -1
  440. package/src/memory/indexer.ts +54 -45
  441. package/src/memory/job-handlers/backfill.ts +2 -11
  442. package/src/memory/job-handlers/cleanup.ts +43 -0
  443. package/src/memory/job-handlers/embedding.ts +6 -8
  444. package/src/memory/job-handlers/summarization.ts +2 -7
  445. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  446. package/src/memory/jobs/embed-concept-page.ts +28 -2
  447. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  448. package/src/memory/jobs-store.ts +114 -22
  449. package/src/memory/jobs-worker.ts +193 -106
  450. package/src/memory/memory-v2-activation-log-store.ts +33 -15
  451. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  452. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  453. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  454. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  455. package/src/memory/migrations/index.ts +6 -0
  456. package/src/memory/migrations/registry.ts +8 -0
  457. package/src/memory/pkb/pkb-search.test.ts +6 -0
  458. package/src/memory/pkb/pkb-search.ts +7 -0
  459. package/src/memory/qdrant-client.ts +49 -32
  460. package/src/memory/rerank-local.ts +374 -0
  461. package/src/memory/schema/infrastructure.ts +15 -0
  462. package/src/memory/search/semantic.ts +13 -67
  463. package/src/memory/sparse-tokenize.ts +49 -0
  464. package/src/memory/trace-event-store.ts +1 -17
  465. package/src/memory/v2/__tests__/activation.test.ts +387 -344
  466. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  467. package/src/memory/v2/__tests__/injection.test.ts +181 -169
  468. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  469. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  470. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  471. package/src/memory/v2/__tests__/sim.test.ts +154 -188
  472. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  473. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  474. package/src/memory/v2/__tests__/static-context.test.ts +76 -2
  475. package/src/memory/v2/activation.ts +213 -239
  476. package/src/memory/v2/consolidation-job.ts +65 -17
  477. package/src/memory/v2/constants.ts +7 -0
  478. package/src/memory/v2/injection.ts +123 -103
  479. package/src/memory/v2/prompts/consolidation.ts +348 -92
  480. package/src/memory/v2/qdrant.ts +198 -1
  481. package/src/memory/v2/reranker.ts +177 -0
  482. package/src/memory/v2/sim.ts +113 -77
  483. package/src/memory/v2/skill-content.ts +4 -3
  484. package/src/memory/v2/skill-store.ts +91 -53
  485. package/src/memory/v2/sparse-bm25.ts +245 -0
  486. package/src/memory/v2/static-context.ts +28 -5
  487. package/src/memory/v2/types.ts +10 -10
  488. package/src/messaging/providers/gmail/types.ts +0 -49
  489. package/src/messaging/providers/slack/adapter.ts +1 -31
  490. package/src/messaging/providers/slack/types.ts +0 -32
  491. package/src/notifications/README.md +10 -10
  492. package/src/notifications/broadcaster.ts +1 -1
  493. package/src/notifications/copy-composer.ts +13 -0
  494. package/src/notifications/guardian-question-mode.ts +5 -5
  495. package/src/notifications/signal.ts +4 -0
  496. package/src/oauth/AGENTS.md +3 -1
  497. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  498. package/src/oauth/connect-orchestrator.ts +6 -0
  499. package/src/oauth/connection-resolver.test.ts +66 -1
  500. package/src/oauth/connection-resolver.ts +55 -1
  501. package/src/oauth/credential-token-resolver.ts +1 -3
  502. package/src/oauth/manual-token-connection.ts +0 -4
  503. package/src/oauth/oauth-connect-state.ts +77 -0
  504. package/src/oauth/seed-providers.ts +58 -1
  505. package/src/outbound-proxy/index.ts +1 -37
  506. package/src/outbound-proxy/logging.ts +1 -1
  507. package/src/outbound-proxy/policy.ts +6 -5
  508. package/src/outbound-proxy/router.ts +2 -1
  509. package/src/permissions/approval-policy.test.ts +6 -275
  510. package/src/permissions/approval-policy.ts +0 -51
  511. package/src/permissions/checker.test.ts +0 -1
  512. package/src/permissions/checker.ts +3 -17
  513. package/src/permissions/gateway-threshold-reader.ts +2 -0
  514. package/src/permissions/prompter.ts +34 -1
  515. package/src/permissions/secret-prompter.ts +6 -2
  516. package/src/plugins/defaults/injectors.ts +35 -2
  517. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  518. package/src/plugins/types.ts +7 -0
  519. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  520. package/src/proactive-artifact/decision.test.ts +226 -0
  521. package/src/proactive-artifact/decision.ts +165 -0
  522. package/src/proactive-artifact/index.ts +7 -0
  523. package/src/proactive-artifact/job.test.ts +867 -0
  524. package/src/proactive-artifact/job.ts +352 -0
  525. package/src/proactive-artifact/message-copy.ts +41 -0
  526. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  527. package/src/proactive-artifact/trigger-state.ts +119 -0
  528. package/src/prompts/bootstrap-cleanup.ts +27 -0
  529. package/src/prompts/normalize-onboarding.ts +80 -0
  530. package/src/prompts/persona-resolver.ts +101 -9
  531. package/src/prompts/system-prompt.ts +23 -24
  532. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  533. package/src/prompts/templates/SOUL.md +13 -1
  534. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  535. package/src/providers/model-intents.ts +7 -0
  536. package/src/providers/openrouter/client.ts +8 -0
  537. package/src/providers/retry.ts +50 -0
  538. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  539. package/src/providers/types.ts +1 -0
  540. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  541. package/src/runtime/agent-wake.ts +238 -100
  542. package/src/runtime/assistant-event-hub.ts +151 -99
  543. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  544. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  545. package/src/runtime/auth/middleware.ts +0 -96
  546. package/src/runtime/auth/route-policy.ts +32 -0
  547. package/src/runtime/auth/same-actor.ts +216 -0
  548. package/src/runtime/btw-sidechain.ts +2 -3
  549. package/src/runtime/channel-invite-transport.ts +2 -48
  550. package/src/runtime/channel-invite-transports/email.ts +1 -1
  551. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  552. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  553. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  554. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  555. package/src/runtime/channel-invite-types.ts +54 -0
  556. package/src/runtime/channel-readiness-service.ts +32 -13
  557. package/src/runtime/channel-retry-sweep.ts +65 -1
  558. package/src/runtime/guardian-reply-router.ts +10 -0
  559. package/src/runtime/http-server.ts +3 -329
  560. package/src/runtime/http-types.ts +0 -5
  561. package/src/runtime/local-actor-identity.ts +52 -11
  562. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  563. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  564. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  565. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  566. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  567. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  568. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  569. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  570. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  571. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  572. package/src/runtime/migrations/migration-transport.ts +7 -7
  573. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  574. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  575. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  576. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  577. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  578. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  579. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  580. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  581. package/src/runtime/pending-interactions.ts +43 -9
  582. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  583. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  584. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
  585. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  586. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  587. package/src/runtime/routes/approval-interception-types.ts +13 -0
  588. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  589. package/src/runtime/routes/backup-routes.ts +15 -38
  590. package/src/runtime/routes/btw-routes.ts +14 -37
  591. package/src/runtime/routes/client-routes.ts +21 -2
  592. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  593. package/src/runtime/routes/contact-routes.ts +0 -25
  594. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  595. package/src/runtime/routes/conversation-routes.ts +65 -39
  596. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  597. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  598. package/src/runtime/routes/document-pdf-renderer.ts +169 -0
  599. package/src/runtime/routes/documents-routes.ts +32 -75
  600. package/src/runtime/routes/errors.ts +19 -4
  601. package/src/runtime/routes/events-routes.ts +38 -0
  602. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  603. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  604. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  605. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  606. package/src/runtime/routes/host-bash-routes.ts +56 -6
  607. package/src/runtime/routes/host-browser-routes.ts +108 -13
  608. package/src/runtime/routes/host-cu-routes.ts +66 -9
  609. package/src/runtime/routes/host-file-routes.ts +54 -5
  610. package/src/runtime/routes/host-transfer-routes.ts +122 -19
  611. package/src/runtime/routes/http-adapter.ts +1 -0
  612. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  613. package/src/runtime/routes/identity-routes.ts +21 -180
  614. package/src/runtime/routes/inbound-message-handler.ts +78 -21
  615. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  616. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  617. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  618. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  619. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  620. package/src/runtime/routes/index.ts +14 -0
  621. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  622. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  623. package/src/runtime/routes/memory-item-routes.ts +10 -12
  624. package/src/runtime/routes/memory-v2-routes.ts +474 -1
  625. package/src/runtime/routes/migration-routes.ts +96 -0
  626. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  627. package/src/runtime/routes/schedule-routes.ts +7 -0
  628. package/src/runtime/verification-outbound-actions.ts +4 -4
  629. package/src/runtime/verification-templates.ts +4 -7
  630. package/src/schedule/integration-status.ts +66 -2
  631. package/src/schedule/recurrence-engine.ts +4 -1
  632. package/src/schedule/retry-backoff.ts +18 -0
  633. package/src/schedule/retry-policy.ts +82 -0
  634. package/src/schedule/run-script.ts +37 -5
  635. package/src/schedule/schedule-recovery.ts +64 -0
  636. package/src/schedule/schedule-store.ts +106 -2
  637. package/src/schedule/scheduler-types.ts +25 -0
  638. package/src/schedule/scheduler.ts +83 -39
  639. package/src/security/encrypted-store.ts +2 -0
  640. package/src/security/oauth-callback-registry.ts +8 -0
  641. package/src/security/secure-keys.ts +55 -0
  642. package/src/sequence/analytics.ts +5 -5
  643. package/src/sequence/engine.ts +1 -1
  644. package/src/skills/catalog-files.ts +2 -8
  645. package/src/skills/include-graph.ts +5 -5
  646. package/src/skills/remote-skill-policy.ts +10 -16
  647. package/src/skills/skill-file-provider.ts +1 -1
  648. package/src/skills/skill-file-types.ts +13 -0
  649. package/src/skills/skillssh-audit-types.ts +28 -0
  650. package/src/skills/skillssh-registry.ts +8 -21
  651. package/src/subagent/index.ts +1 -7
  652. package/src/subagent/manager.ts +1 -15
  653. package/src/tasks/task-runner.ts +0 -1
  654. package/src/tasks/task-store.ts +0 -3
  655. package/src/telemetry/types.ts +2 -0
  656. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  657. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  658. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  659. package/src/tools/apps/executors.ts +56 -69
  660. package/src/tools/background-tool-registry.ts +17 -3
  661. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  662. package/src/tools/browser/browser-execution.ts +2 -2
  663. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  664. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  665. package/src/tools/browser/cdp-client/factory.ts +23 -24
  666. package/src/tools/browser/cdp-client/index.ts +1 -14
  667. package/src/tools/computer-use/definitions.ts +42 -20
  668. package/src/tools/executor.ts +2 -0
  669. package/src/tools/host-filesystem/edit.test.ts +151 -0
  670. package/src/tools/host-filesystem/edit.ts +68 -0
  671. package/src/tools/host-filesystem/read.test.ts +129 -0
  672. package/src/tools/host-filesystem/read.ts +68 -0
  673. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  674. package/src/tools/host-filesystem/transfer.ts +78 -3
  675. package/src/tools/host-filesystem/write.test.ts +134 -0
  676. package/src/tools/host-filesystem/write.ts +68 -0
  677. package/src/tools/host-terminal/host-shell.ts +66 -1
  678. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  679. package/src/tools/memory/register.test.ts +12 -9
  680. package/src/tools/memory/register.ts +1 -2
  681. package/src/tools/provider-tool-name.ts +28 -0
  682. package/src/tools/registry.ts +30 -9
  683. package/src/tools/schedule/create.ts +6 -0
  684. package/src/tools/schedule/list.ts +2 -0
  685. package/src/tools/schedule/update.ts +10 -0
  686. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  687. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  688. package/src/tools/skills/load.ts +0 -32
  689. package/src/tools/terminal/shell.ts +9 -1
  690. package/src/tools/tool-approval-handler.ts +32 -11
  691. package/src/tools/types.ts +28 -2
  692. package/src/tts/provider-catalog.ts +3 -5
  693. package/src/usage/pricing.ts +1 -1
  694. package/src/util/disk-usage.ts +138 -0
  695. package/src/util/platform.ts +21 -11
  696. package/src/util/process-liveness.ts +26 -0
  697. package/src/workspace/hatched-date.ts +86 -0
  698. package/src/workspace/heartbeat-service.ts +19 -0
  699. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  700. package/src/workspace/migrations/006-services-config.ts +8 -5
  701. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  702. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  703. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  704. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  705. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  706. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  707. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  708. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  709. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  710. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  711. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  712. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  713. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  714. package/src/workspace/migrations/AGENTS.md +1 -1
  715. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  716. package/src/workspace/migrations/registry.ts +8 -0
  717. package/src/workspace/migrations/utils.ts +21 -0
  718. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  719. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  720. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  721. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  722. package/src/__tests__/twilio-rest.test.ts +0 -34
  723. package/src/backup/__tests__/backup-key.test.ts +0 -152
  724. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  725. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  726. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  727. package/src/backup/backup-key.ts +0 -137
  728. package/src/backup/backup-worker.ts +0 -472
  729. package/src/backup/offsite-writer.ts +0 -222
  730. package/src/backup/stream-crypt.ts +0 -263
  731. package/src/daemon/message-types/pairing.ts +0 -58
  732. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  733. package/src/memory/v2/skill-qdrant.ts +0 -395
  734. package/src/outbound-proxy/config.ts +0 -20
  735. package/src/outbound-proxy/health.ts +0 -18
  736. package/src/outbound-proxy/types.ts +0 -150
  737. package/src/runtime/capability-tokens.ts +0 -190
  738. package/src/signals/bash.ts +0 -198
  739. package/src/signals/mcp-reload.ts +0 -18
@@ -1,11 +1,14 @@
1
1
  import { v4 as uuid } from "uuid";
2
2
 
3
- import { buildAssistantEvent } from "../runtime/assistant-event.js";
4
- import { assistantEventHub } from "../runtime/assistant-event-hub.js";
3
+ import type { InterfaceId } from "../channels/types.js";
4
+ import {
5
+ assistantEventHub,
6
+ broadcastMessage,
7
+ } from "../runtime/assistant-event-hub.js";
8
+ import * as pendingInteractions from "../runtime/pending-interactions.js";
5
9
  import type { ToolExecutionResult } from "../tools/types.js";
6
10
  import { AssistantError, ErrorCode } from "../util/errors.js";
7
11
  import { getLogger } from "../util/logger.js";
8
- import type { ServerMessage } from "./message-protocol.js";
9
12
  import type { HostBrowserRequest } from "./message-types/host-browser.js";
10
13
 
11
14
  /** Distributive omit that preserves union variant fields. */
@@ -21,13 +24,11 @@ export type HostBrowserInput = DistributiveOmit<
21
24
 
22
25
  const log = getLogger("host-browser-proxy");
23
26
 
24
- interface PendingRequest {
25
- resolve: (result: ToolExecutionResult) => void;
26
- reject: (err: Error) => void;
27
- timer: ReturnType<typeof setTimeout>;
28
- /** Detach the abort listener from the caller's signal. No-op when no signal was passed. */
29
- detachAbort: () => void;
30
- }
27
+ /** Interface priority order for host_browser: Chrome Extension first, macOS SSE bridge second. */
28
+ const HOST_BROWSER_INTERFACE_PREFERENCE: InterfaceId[] = [
29
+ "chrome-extension",
30
+ "macos",
31
+ ];
31
32
 
32
33
  export class HostBrowserProxy {
33
34
  private static _instance: HostBrowserProxy | null = null;
@@ -58,29 +59,29 @@ export class HostBrowserProxy {
58
59
  HostBrowserProxy._instance = null;
59
60
  }
60
61
 
61
- private pending = new Map<string, PendingRequest>();
62
-
63
62
  /**
64
63
  * Whether a client with `host_browser` capability is connected.
64
+ * Returns `true` when either the Chrome Extension or the macOS SSE
65
+ * bridge is available — i.e. any transport can forward host-browser
66
+ * requests.
65
67
  */
66
68
  isAvailable(): boolean {
67
69
  return (
68
- assistantEventHub.getMostRecentClientByCapability("host_browser") != null
70
+ assistantEventHub.getPreferredClientByCapability(
71
+ "host_browser",
72
+ HOST_BROWSER_INTERFACE_PREFERENCE,
73
+ ) != null
69
74
  );
70
75
  }
71
76
 
72
77
  /**
73
- * Publish a ServerMessage through the assistant event hub, targeted at
74
- * subscribers with the `host_browser` capability.
78
+ * Whether a Chrome Extension client specifically is connected.
79
+ * Returns `false` when only the macOS SSE bridge is available.
80
+ * Unlike {@link isAvailable}, this does not consider the macOS bridge
81
+ * a valid extension transport.
75
82
  */
76
- private send(msg: ServerMessage): void {
77
- void assistantEventHub
78
- .publish(buildAssistantEvent(msg), {
79
- targetCapability: "host_browser",
80
- })
81
- .catch((err) => {
82
- log.warn({ err }, "failed to publish host_browser event to hub");
83
- });
83
+ hasExtensionClient(): boolean {
84
+ return assistantEventHub.listClientsByInterface("chrome-extension").length > 0;
84
85
  }
85
86
 
86
87
  request(
@@ -95,42 +96,34 @@ export class HostBrowserProxy {
95
96
  const requestId = uuid();
96
97
 
97
98
  return new Promise<ToolExecutionResult>((resolve, reject) => {
98
- // CDP operations should be fast — 30 second default timeout matches host_file.
99
99
  const timeoutSec = input.timeout_seconds ?? 30;
100
100
 
101
- // Declared up-front so onAbort (defined before detachAbort is assigned)
102
- // can close over a stable reference once it's wired below.
103
101
  let detachAbort: () => void = () => {};
104
102
 
105
103
  const timer = setTimeout(() => {
106
- this.pending.delete(requestId);
107
- detachAbort();
104
+ pendingInteractions.resolve(requestId);
108
105
  log.warn(
109
106
  { requestId, cdpMethod: input.cdpMethod },
110
107
  "Host browser proxy request timed out",
111
108
  );
112
109
  resolve({
113
110
  content:
114
- "Host browser proxy timed out waiting for extension response (check browser-relay connectivity and /v1/host-browser-result callback failures such as 404/401).",
111
+ "Host browser proxy timed out waiting for extension response (check SSE connectivity and /v1/host-browser-result callback failures such as 404/401).",
115
112
  isError: true,
116
113
  });
117
114
  }, timeoutSec * 1000);
118
115
 
119
116
  if (signal) {
120
117
  const onAbort = () => {
121
- if (this.pending.has(requestId)) {
122
- clearTimeout(timer);
123
- this.pending.delete(requestId);
124
- // Abort fired — nothing to detach, but call the no-op for symmetry
125
- // so callers can rely on detachAbort being idempotent.
126
- detachAbort();
118
+ if (pendingInteractions.get(requestId)) {
119
+ pendingInteractions.resolve(requestId);
127
120
  try {
128
- this.send({
121
+ broadcastMessage({
129
122
  type: "host_browser_cancel",
130
123
  requestId,
131
- } as ServerMessage);
124
+ });
132
125
  } catch {
133
- // Best-effort cancel notification — connection may already be closed.
126
+ // Best-effort cancel notification
134
127
  }
135
128
  resolve({ content: "Aborted", isError: true });
136
129
  }
@@ -139,13 +132,22 @@ export class HostBrowserProxy {
139
132
  detachAbort = () => signal.removeEventListener("abort", onAbort);
140
133
  }
141
134
 
142
- this.pending.set(requestId, { resolve, reject, timer, detachAbort });
135
+ pendingInteractions.register(requestId, {
136
+ conversationId,
137
+ kind: "host_browser",
138
+ rpcResolve: resolve,
139
+ rpcReject: reject,
140
+ timer,
141
+ detachAbort,
142
+ });
143
143
 
144
144
  try {
145
- if (!this.isAvailable()) {
146
- clearTimeout(timer);
147
- this.pending.delete(requestId);
148
- detachAbort();
145
+ const preferredClient = assistantEventHub.getPreferredClientByCapability(
146
+ "host_browser",
147
+ HOST_BROWSER_INTERFACE_PREFERENCE,
148
+ );
149
+ if (!preferredClient) {
150
+ pendingInteractions.resolve(requestId);
149
151
  reject(
150
152
  new Error(
151
153
  "host_browser send failed: no active extension connection",
@@ -154,19 +156,13 @@ export class HostBrowserProxy {
154
156
  return;
155
157
  }
156
158
 
157
- this.send({
158
- ...input,
159
- type: "host_browser_request",
160
- requestId,
159
+ broadcastMessage(
160
+ { ...input, type: "host_browser_request", requestId, conversationId },
161
161
  conversationId,
162
- } as ServerMessage);
162
+ { targetClientId: preferredClient.clientId },
163
+ );
163
164
  } catch (err) {
164
- // Sender threw synchronously (e.g. client transport error during
165
- // event emission). Clean up pending state and timer so we don't
166
- // leak an in-flight entry that nothing will ever resolve.
167
- clearTimeout(timer);
168
- this.pending.delete(requestId);
169
- detachAbort();
165
+ pendingInteractions.resolve(requestId);
170
166
  log.warn(
171
167
  { requestId, cdpMethod: input.cdpMethod, err },
172
168
  "Host browser proxy send failed",
@@ -176,55 +172,44 @@ export class HostBrowserProxy {
176
172
  });
177
173
  }
178
174
 
179
- resolve(
175
+ /**
176
+ * Process a client result and resolve the RPC. Called by route handlers.
177
+ */
178
+ resolveResult(
180
179
  requestId: string,
181
180
  response: { content: string; isError: boolean },
182
181
  ): void {
183
- const entry = this.pending.get(requestId);
184
- if (!entry) {
185
- // Benign race, not an error. A late result frame with no matching
186
- // pending entry means one of:
187
- // - the proxy-side setTimeout has already resolved the caller;
188
- // - the caller's AbortSignal fired and the entry was torn down;
189
- // - a duplicate result frame was delivered (e.g. retry after a
190
- // transient WS drop).
191
- // Log at debug so operators don't chase false-positive "timeout"
192
- // alerts on what is actually a cleanly-handled race.
182
+ const interaction = pendingInteractions.resolve(requestId);
183
+ if (!interaction?.rpcResolve) {
193
184
  log.debug(
194
185
  { requestId },
195
186
  "Ignoring host_browser_result for unknown or already-resolved request",
196
187
  );
197
188
  return;
198
189
  }
199
- clearTimeout(entry.timer);
200
- entry.detachAbort();
201
- this.pending.delete(requestId);
202
- entry.resolve({ content: response.content, isError: response.isError });
203
- }
204
-
205
- hasPendingRequest(requestId: string): boolean {
206
- return this.pending.has(requestId);
190
+ interaction.rpcResolve({
191
+ content: response.content,
192
+ isError: response.isError,
193
+ });
207
194
  }
208
195
 
209
196
  dispose(): void {
210
- for (const [requestId, entry] of this.pending) {
211
- clearTimeout(entry.timer);
212
- entry.detachAbort();
197
+ for (const entry of pendingInteractions.getByKind("host_browser")) {
198
+ pendingInteractions.resolve(entry.requestId);
213
199
  try {
214
- this.send({
200
+ broadcastMessage({
215
201
  type: "host_browser_cancel",
216
- requestId,
217
- } as ServerMessage);
202
+ requestId: entry.requestId,
203
+ });
218
204
  } catch {
219
- // Best-effort cancel notification — connection may already be closed.
205
+ // Best-effort cancel notification
220
206
  }
221
- entry.reject(
207
+ entry.rpcReject?.(
222
208
  new AssistantError(
223
209
  "Host browser proxy disposed",
224
210
  ErrorCode.INTERNAL_ERROR,
225
211
  ),
226
212
  );
227
213
  }
228
- this.pending.clear();
229
214
  }
230
215
  }
@@ -9,6 +9,9 @@
9
9
  * Unlike HostBashProxy/HostFileProxy/HostTransferProxy, this is NOT a
10
10
  * singleton — each conversation gets its own instance because CU state
11
11
  * (step count, AX tree history, loop detection) is per-conversation.
12
+ *
13
+ * RPC lifecycle (resolve/reject/timer/detachAbort) is stored in
14
+ * pendingInteractions alongside routing metadata.
12
15
  */
13
16
 
14
17
  import { v4 as uuid } from "uuid";
@@ -20,11 +23,11 @@ import {
20
23
  assistantEventHub,
21
24
  broadcastMessage,
22
25
  } from "../runtime/assistant-event-hub.js";
26
+ import { enforceSameActorOrErrorResult } from "../runtime/auth/same-actor.js";
23
27
  import * as pendingInteractions from "../runtime/pending-interactions.js";
24
28
  import type { ToolExecutionResult } from "../tools/types.js";
25
29
  import { AssistantError, ErrorCode } from "../util/errors.js";
26
30
  import { getLogger } from "../util/logger.js";
27
- import type { ServerMessage } from "./message-protocol.js";
28
31
 
29
32
  const log = getLogger("host-cu-proxy");
30
33
 
@@ -62,28 +65,19 @@ export interface ActionRecord {
62
65
  reasoning?: string;
63
66
  }
64
67
 
65
- interface PendingRequest {
66
- resolve: (result: ToolExecutionResult) => void;
67
- reject: (err: Error) => void;
68
- timer: ReturnType<typeof setTimeout>;
69
- conversationId: string;
70
- /** Detach the abort listener from the caller's signal. No-op when no signal was passed. */
71
- detachAbort: () => void;
72
- }
73
-
74
68
  // ---------------------------------------------------------------------------
75
69
  // HostCuProxy
76
70
  // ---------------------------------------------------------------------------
77
71
 
78
72
  export class HostCuProxy {
79
- private pending = new Map<string, PendingRequest>();
80
-
81
73
  // CU state tracking (per-conversation)
82
74
  private _stepCount = 0;
83
75
  private _maxSteps: number;
84
76
  private _previousAXTree: string | undefined;
85
77
  private _consecutiveUnchangedSteps = 0;
86
78
  private _actionHistory: ActionRecord[] = [];
79
+ /** Request IDs owned by this instance — used to scope dispose(). */
80
+ private _ownedRequests = new Set<string>();
87
81
 
88
82
  constructor(maxSteps = loadConfig().maxStepsPerSession) {
89
83
  this._maxSteps = maxSteps;
@@ -121,23 +115,23 @@ export class HostCuProxy {
121
115
  * Whether a client with `host_cu` capability is connected.
122
116
  */
123
117
  isAvailable(): boolean {
124
- return (
125
- assistantEventHub.getMostRecentClientByCapability("host_cu") != null
126
- );
127
- }
128
-
129
- // ---------------------------------------------------------------------------
130
- // Send helper
131
- // ---------------------------------------------------------------------------
132
-
133
- private send(msg: ServerMessage): void {
134
- broadcastMessage(msg, undefined, { targetCapability: "host_cu" });
118
+ return assistantEventHub.getMostRecentClientByCapability("host_cu") != null;
135
119
  }
136
120
 
137
121
  // ---------------------------------------------------------------------------
138
122
  // Request / resolve lifecycle
139
123
  // ---------------------------------------------------------------------------
140
124
 
125
+ /**
126
+ * Send a CU request to the connected desktop client.
127
+ *
128
+ * When `targetClientId` is supplied, the proxy validates that the target
129
+ * exists and advertises the `host_cu` capability, mirroring HostFileProxy's
130
+ * resolver-side checks so that the proxy is safe to call as a standalone
131
+ * API. It additionally enforces that the caller (`sourceActorPrincipalId`)
132
+ * and the target client share the same actor principal — cross-user
133
+ * targeted dispatch is rejected.
134
+ */
141
135
  request(
142
136
  toolName: string,
143
137
  input: Record<string, unknown>,
@@ -145,6 +139,8 @@ export class HostCuProxy {
145
139
  stepNumber: number,
146
140
  reasoning?: string,
147
141
  signal?: AbortSignal,
142
+ targetClientId?: string,
143
+ sourceActorPrincipalId?: string,
148
144
  ): Promise<ToolExecutionResult> {
149
145
  if (signal?.aborted) {
150
146
  return Promise.resolve({
@@ -153,7 +149,6 @@ export class HostCuProxy {
153
149
  });
154
150
  }
155
151
 
156
- // Enforce step limit before sending to client
157
152
  if (this._stepCount > this._maxSteps) {
158
153
  return Promise.resolve({
159
154
  content: `Step limit (${this._maxSteps}) exceeded. Call computer_use_done to finish.`,
@@ -161,14 +156,45 @@ export class HostCuProxy {
161
156
  });
162
157
  }
163
158
 
159
+ // Existence + capability validation for explicit targets. Mirrors
160
+ // HostFileProxy's resolver-side guard so that the proxy is safe even
161
+ // when called outside the conversation-surfaces dispatch (which has
162
+ // its own validation layer).
163
+ if (targetClientId != null) {
164
+ const client = assistantEventHub.getClientById(targetClientId);
165
+ if (!client) {
166
+ return Promise.resolve({
167
+ content: `No connected client with id '${targetClientId}' supports host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
168
+ isError: true,
169
+ });
170
+ }
171
+ if (!client.capabilities.includes("host_cu")) {
172
+ return Promise.resolve({
173
+ content: `Client '${targetClientId}' does not support host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
174
+ isError: true,
175
+ });
176
+ }
177
+
178
+ // Same-user enforcement: targeted CU dispatch must be owned by the
179
+ // same actor on both sides. This is the authoritative gate — the
180
+ // dispatch layer (conversation-surfaces.ts) skips its own check
181
+ // and relies on the proxy.
182
+ const rejection = enforceSameActorOrErrorResult({
183
+ hub: assistantEventHub,
184
+ sourceActorPrincipalId,
185
+ targetClientId,
186
+ op: "host_cu",
187
+ });
188
+ if (rejection) return Promise.resolve(rejection);
189
+ }
190
+
164
191
  const requestId = uuid();
165
192
 
166
193
  return new Promise<ToolExecutionResult>((resolve, reject) => {
167
194
  let detachAbort: () => void = () => {};
168
195
 
169
196
  const timer = setTimeout(() => {
170
- this.pending.delete(requestId);
171
- detachAbort();
197
+ this._ownedRequests.delete(requestId);
172
198
  pendingInteractions.resolve(requestId);
173
199
  log.warn({ requestId, toolName }, "Host CU proxy request timed out");
174
200
  resolve({
@@ -179,19 +205,22 @@ export class HostCuProxy {
179
205
 
180
206
  if (signal) {
181
207
  const onAbort = () => {
182
- if (this.pending.has(requestId)) {
183
- clearTimeout(timer);
184
- this.pending.delete(requestId);
185
- detachAbort();
208
+ if (pendingInteractions.get(requestId)) {
209
+ this._ownedRequests.delete(requestId);
186
210
  pendingInteractions.resolve(requestId);
187
211
  try {
188
- this.send({
189
- type: "host_cu_cancel",
190
- requestId,
212
+ broadcastMessage(
213
+ {
214
+ type: "host_cu_cancel",
215
+ requestId,
216
+ conversationId,
217
+ ...(targetClientId != null ? { targetClientId } : {}),
218
+ },
191
219
  conversationId,
192
- });
220
+ { targetClientId },
221
+ );
193
222
  } catch {
194
- // Best-effort cancel notification — connection may already be closed.
223
+ // Best-effort cancel notification
195
224
  }
196
225
  resolve({ content: "Aborted", isError: true });
197
226
  }
@@ -200,22 +229,40 @@ export class HostCuProxy {
200
229
  detachAbort = () => signal.removeEventListener("abort", onAbort);
201
230
  }
202
231
 
203
- this.pending.set(requestId, { resolve, reject, timer, conversationId, detachAbort });
232
+ this._ownedRequests.add(requestId);
233
+
234
+ pendingInteractions.register(requestId, {
235
+ conversationId,
236
+ kind: "host_cu",
237
+ targetClientId,
238
+ targetActorPrincipalId:
239
+ targetClientId != null
240
+ ? assistantEventHub.getActorPrincipalIdForClient(targetClientId)
241
+ : undefined,
242
+ rpcResolve: resolve,
243
+ rpcReject: reject,
244
+ timer,
245
+ detachAbort,
246
+ });
204
247
 
205
248
  try {
206
- this.send({
207
- type: "host_cu_request",
208
- requestId,
249
+ broadcastMessage(
250
+ {
251
+ type: "host_cu_request",
252
+ requestId,
253
+ conversationId,
254
+ toolName,
255
+ input,
256
+ stepNumber,
257
+ reasoning,
258
+ // Include in body so receiving client can verify targeted endpoint.
259
+ ...(targetClientId != null ? { targetClientId } : {}),
260
+ },
209
261
  conversationId,
210
- toolName,
211
- input,
212
- stepNumber,
213
- reasoning,
214
- });
262
+ { targetClientId },
263
+ );
215
264
  } catch (err) {
216
- clearTimeout(timer);
217
- this.pending.delete(requestId);
218
- detachAbort();
265
+ this._ownedRequests.delete(requestId);
219
266
  pendingInteractions.resolve(requestId);
220
267
  log.warn({ requestId, toolName, err }, "Host CU proxy send failed");
221
268
  reject(err instanceof Error ? err : new Error(String(err)));
@@ -223,28 +270,27 @@ export class HostCuProxy {
223
270
  });
224
271
  }
225
272
 
226
- resolve(requestId: string, observation: CuObservationResult): void {
227
- const entry = this.pending.get(requestId);
228
- if (!entry) {
273
+ /**
274
+ * Process a CU observation from the client and resolve the RPC.
275
+ * Updates CU state (step tracking, AX tree history) and formats
276
+ * the observation into a ToolExecutionResult.
277
+ */
278
+ processObservation(
279
+ requestId: string,
280
+ observation: CuObservationResult,
281
+ ): ToolExecutionResult | undefined {
282
+ this._ownedRequests.delete(requestId);
283
+ const interaction = pendingInteractions.resolve(requestId);
284
+ if (!interaction?.rpcResolve) {
229
285
  log.warn({ requestId }, "No pending host CU request for response");
230
- return;
286
+ return undefined;
231
287
  }
232
- clearTimeout(entry.timer);
233
- entry.detachAbort();
234
- this.pending.delete(requestId);
235
288
 
236
- // Capture pre-update state so formatObservation sees the correct previous AX tree
237
289
  const prevAXTree = this._previousAXTree;
238
-
239
- // Update CU state from observation
240
290
  this.updateStateFromObservation(observation);
241
-
242
291
  const result = this.formatObservation(observation, prevAXTree);
243
- entry.resolve(result);
244
- }
245
-
246
- hasPendingRequest(requestId: string): boolean {
247
- return this.pending.has(requestId);
292
+ interaction.rpcResolve(result);
293
+ return result;
248
294
  }
249
295
 
250
296
  // ---------------------------------------------------------------------------
@@ -267,7 +313,6 @@ export class HostCuProxy {
267
313
  input,
268
314
  reasoning,
269
315
  });
270
- // Keep history bounded
271
316
  if (this._actionHistory.length > MAX_HISTORY_ENTRIES) {
272
317
  this._actionHistory = this._actionHistory.slice(-MAX_HISTORY_ENTRIES);
273
318
  }
@@ -297,7 +342,6 @@ export class HostCuProxy {
297
342
  const prevTree = previousAXTree;
298
343
  const parts: string[] = [];
299
344
 
300
- // Surface user guidance prominently so the model sees it first
301
345
  if (obs.userGuidance) {
302
346
  parts.push(`USER GUIDANCE: ${obs.userGuidance}`);
303
347
  parts.push("");
@@ -308,12 +352,10 @@ export class HostCuProxy {
308
352
  parts.push("");
309
353
  }
310
354
 
311
- // AX tree diff / unchanged warning
312
355
  if (obs.axDiff) {
313
356
  parts.push(obs.axDiff);
314
357
  parts.push("");
315
358
  } else if (prevTree != null && obs.axTree != null) {
316
- // Skip unchanged warning after wait actions — they intentionally yield no immediate change
317
359
  const lastAction =
318
360
  this._actionHistory.length > 0
319
361
  ? this._actionHistory[this._actionHistory.length - 1]
@@ -321,7 +363,6 @@ export class HostCuProxy {
321
363
  const isWaitAction = lastAction?.toolName === "computer_use_wait";
322
364
 
323
365
  if (!isWaitAction) {
324
- // No diff means the screen didn't change
325
366
  if (
326
367
  this._consecutiveUnchangedSteps >=
327
368
  CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD
@@ -338,7 +379,6 @@ export class HostCuProxy {
338
379
  }
339
380
  }
340
381
 
341
- // Loop detection: identical actions repeated
342
382
  if (this._actionHistory.length >= LOOP_DETECTION_WINDOW) {
343
383
  const recent = this._actionHistory.slice(-LOOP_DETECTION_WINDOW);
344
384
  const allIdentical = recent.every(
@@ -354,7 +394,6 @@ export class HostCuProxy {
354
394
  }
355
395
  }
356
396
 
357
- // Current screen state wrapped in markers for history compaction
358
397
  if (obs.axTree) {
359
398
  parts.push("<ax-tree>");
360
399
  parts.push("CURRENT SCREEN STATE:");
@@ -362,7 +401,6 @@ export class HostCuProxy {
362
401
  parts.push("</ax-tree>");
363
402
  }
364
403
 
365
- // Secondary windows for cross-app awareness
366
404
  if (obs.secondaryWindows) {
367
405
  parts.push("");
368
406
  parts.push(obs.secondaryWindows);
@@ -372,7 +410,6 @@ export class HostCuProxy {
372
410
  );
373
411
  }
374
412
 
375
- // Screenshot metadata
376
413
  const screenshotMeta = this.formatScreenshotMetadata(obs);
377
414
  if (screenshotMeta.length > 0) {
378
415
  parts.push("");
@@ -381,7 +418,6 @@ export class HostCuProxy {
381
418
 
382
419
  const content = parts.join("\n").trim() || "Action executed";
383
420
 
384
- // Build content blocks for screenshot
385
421
  const contentBlocks: ContentBlock[] = [];
386
422
  if (obs.screenshot) {
387
423
  contentBlocks.push({
@@ -410,31 +446,36 @@ export class HostCuProxy {
410
446
  // ---------------------------------------------------------------------------
411
447
 
412
448
  dispose(): void {
413
- for (const [requestId, entry] of this.pending) {
414
- clearTimeout(entry.timer);
415
- entry.detachAbort();
416
- pendingInteractions.resolve(requestId);
449
+ for (const requestId of this._ownedRequests) {
450
+ const entry = pendingInteractions.resolve(requestId);
451
+ if (!entry) continue;
417
452
  try {
418
- this.send({
419
- type: "host_cu_cancel",
420
- requestId,
421
- conversationId: entry.conversationId,
422
- });
453
+ broadcastMessage(
454
+ {
455
+ type: "host_cu_cancel",
456
+ requestId,
457
+ conversationId: entry.conversationId,
458
+ ...(entry.targetClientId != null
459
+ ? { targetClientId: entry.targetClientId }
460
+ : {}),
461
+ },
462
+ entry.conversationId,
463
+ { targetClientId: entry.targetClientId as string | undefined },
464
+ );
423
465
  } catch {
424
- // Best-effort cancel notification — connection may already be closed.
466
+ // Best-effort cancel notification
425
467
  }
426
- entry.reject(
468
+ entry.rpcReject?.(
427
469
  new AssistantError("Host CU proxy disposed", ErrorCode.INTERNAL_ERROR),
428
470
  );
429
471
  }
430
- this.pending.clear();
472
+ this._ownedRequests.clear();
431
473
  }
432
474
 
433
475
  // ---------------------------------------------------------------------------
434
476
  // Private helpers
435
477
  // ---------------------------------------------------------------------------
436
478
 
437
- /** Update consecutive-unchanged tracking from an incoming observation. */
438
479
  private updateStateFromObservation(obs: CuObservationResult): void {
439
480
  if (this._stepCount > 0) {
440
481
  if (