@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
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Route handler for host app-control result submissions.
3
+ *
4
+ * Resolves pending host app-control proxy requests by requestId when the
5
+ * desktop client returns observation/action results via HTTP. App-control
6
+ * sessions are per-conversation (not a singleton like host-browser), so we
7
+ * look up the owning conversation through the pending-interactions tracker
8
+ * and forward the payload to that conversation's `hostAppControlProxy`.
9
+ *
10
+ * Late-delivery tolerance: returns 200 even when no pending interaction
11
+ * matches (e.g. the conversation was disposed before the client reported
12
+ * back). The proxy is best-effort — there is no consumer to notify, so a
13
+ * 4xx would only confuse a client that already executed the action.
14
+ */
15
+ import { z } from "zod";
16
+
17
+ import { findConversation } from "../../daemon/conversation-store.js";
18
+ import type {
19
+ HostAppControlResultPayload,
20
+ HostAppControlState,
21
+ } from "../../daemon/message-types/host-app-control.js";
22
+ import * as pendingInteractions from "../pending-interactions.js";
23
+ import { BadRequestError } from "./errors.js";
24
+ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
25
+
26
+ const VALID_STATES: ReadonlySet<HostAppControlState> = new Set([
27
+ "running",
28
+ "missing",
29
+ "minimized",
30
+ ]);
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // POST /v1/host-app-control-result
34
+ // ---------------------------------------------------------------------------
35
+
36
+ function handleHostAppControlResult({ body }: RouteHandlerArgs) {
37
+ if (!body || typeof body !== "object") {
38
+ throw new BadRequestError("Request body is required");
39
+ }
40
+
41
+ const {
42
+ requestId,
43
+ state,
44
+ pngBase64,
45
+ windowBounds,
46
+ executionResult,
47
+ executionError,
48
+ } = body as {
49
+ requestId?: string;
50
+ state?: string;
51
+ pngBase64?: string;
52
+ windowBounds?: { x: number; y: number; width: number; height: number };
53
+ executionResult?: string;
54
+ executionError?: string;
55
+ };
56
+
57
+ if (!requestId || typeof requestId !== "string") {
58
+ throw new BadRequestError("requestId is required");
59
+ }
60
+
61
+ if (!state || !VALID_STATES.has(state as HostAppControlState)) {
62
+ throw new BadRequestError(
63
+ "state must be one of: running, missing, minimized",
64
+ );
65
+ }
66
+
67
+ // Late-delivery tolerance: if the pending interaction is already gone (the
68
+ // proxy timed out, the conversation was disposed, etc.), accept the post
69
+ // and move on. There is no consumer left to fail loudly to.
70
+ const peeked = pendingInteractions.get(requestId);
71
+ if (!peeked || peeked.kind !== "host_app_control") {
72
+ return { accepted: true };
73
+ }
74
+
75
+ const interaction = pendingInteractions.resolve(requestId)!;
76
+ const conversation = findConversation(interaction.conversationId);
77
+ if (!conversation) {
78
+ return { accepted: true };
79
+ }
80
+
81
+ const payload: HostAppControlResultPayload = {
82
+ requestId,
83
+ state: state as HostAppControlState,
84
+ ...(pngBase64 !== undefined ? { pngBase64 } : {}),
85
+ ...(windowBounds !== undefined ? { windowBounds } : {}),
86
+ ...(executionResult !== undefined ? { executionResult } : {}),
87
+ ...(executionError !== undefined ? { executionError } : {}),
88
+ };
89
+
90
+ conversation.hostAppControlProxy?.resolve(requestId, payload);
91
+
92
+ return { accepted: true };
93
+ }
94
+
95
+ // ---------------------------------------------------------------------------
96
+ // Route definitions (shared HTTP + IPC)
97
+ // ---------------------------------------------------------------------------
98
+
99
+ export const ROUTES: RouteDefinition[] = [
100
+ {
101
+ operationId: "host_app_control_result",
102
+ endpoint: "host-app-control-result",
103
+ method: "POST",
104
+ requireGuardian: true,
105
+ summary: "Submit host app-control result",
106
+ description:
107
+ "Resolve a pending host app-control request by requestId. Returns 200 even when no pending interaction matches (late delivery is tolerated).",
108
+ tags: ["host"],
109
+ requestBody: z.object({
110
+ requestId: z.string().describe("Pending app-control request ID"),
111
+ state: z
112
+ .enum(["running", "missing", "minimized"])
113
+ .describe("Lifecycle state of the targeted application"),
114
+ pngBase64: z
115
+ .string()
116
+ .describe("Base64 PNG screenshot of the targeted app window")
117
+ .optional(),
118
+ windowBounds: z
119
+ .object({
120
+ x: z.number(),
121
+ y: z.number(),
122
+ width: z.number(),
123
+ height: z.number(),
124
+ })
125
+ .optional(),
126
+ executionResult: z.string().optional(),
127
+ executionError: z.string().optional(),
128
+ }),
129
+ responseBody: z.object({
130
+ accepted: z.boolean(),
131
+ }),
132
+ handler: handleHostAppControlResult,
133
+ },
134
+ ];
@@ -7,10 +7,16 @@
7
7
  import { z } from "zod";
8
8
 
9
9
  import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
10
+ import {
11
+ enforceSameActorOrThrow,
12
+ SAME_ACTOR_FORBIDDEN_DESCRIPTION,
13
+ } from "../auth/same-actor.js";
14
+ import { resolveActorPrincipalIdForLocalGuardian } from "../local-actor-identity.js";
10
15
  import * as pendingInteractions from "../pending-interactions.js";
11
16
  import {
12
17
  BadRequestError,
13
18
  ConflictError,
19
+ ForbiddenError,
14
20
  NotFoundError,
15
21
  } from "./errors.js";
16
22
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
@@ -19,7 +25,7 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
19
25
  // POST /v1/host-bash-result
20
26
  // ---------------------------------------------------------------------------
21
27
 
22
- function handleHostBashResult({ body }: RouteHandlerArgs) {
28
+ function handleHostBashResult({ body, headers }: RouteHandlerArgs) {
23
29
  if (!body || typeof body !== "object") {
24
30
  throw new BadRequestError("Request body is required");
25
31
  }
@@ -36,11 +42,15 @@ function handleHostBashResult({ body }: RouteHandlerArgs) {
36
42
  throw new BadRequestError("requestId is required");
37
43
  }
38
44
 
45
+ const submittingClientId =
46
+ headers?.["x-vellum-client-id"]?.trim() || undefined;
47
+ const submittingActorPrincipalId = resolveActorPrincipalIdForLocalGuardian(
48
+ headers?.["x-vellum-actor-principal-id"]?.trim() || undefined,
49
+ );
50
+
39
51
  const peeked = pendingInteractions.get(requestId);
40
52
  if (!peeked) {
41
- throw new NotFoundError(
42
- "No pending interaction found for this requestId",
43
- );
53
+ throw new NotFoundError("No pending interaction found for this requestId");
44
54
  }
45
55
 
46
56
  if (peeked.kind !== "host_bash") {
@@ -49,9 +59,33 @@ function handleHostBashResult({ body }: RouteHandlerArgs) {
49
59
  );
50
60
  }
51
61
 
52
- pendingInteractions.resolve(requestId);
62
+ const { targetClientId } = peeked;
63
+ if (targetClientId) {
64
+ if (!submittingClientId) {
65
+ throw new BadRequestError(
66
+ "x-vellum-client-id header is required for targeted host bash requests",
67
+ );
68
+ }
69
+ if (submittingClientId !== targetClientId) {
70
+ throw new ForbiddenError(
71
+ `Client "${submittingClientId}" is not the target for this request (expected "${targetClientId}"). The targeted client must submit the result.`,
72
+ );
73
+ }
74
+
75
+ // Defense-in-depth on top of the client-id header binding above: the
76
+ // submitting actor's principal must match the actor principal stored
77
+ // for the target client at SSE subscription time. This prevents a
78
+ // cross-user submission even when the attacker can guess or spoof the
79
+ // target's client ID.
80
+ enforceSameActorOrThrow({
81
+ sourceActorPrincipalId: submittingActorPrincipalId,
82
+ targetActorPrincipalId: peeked.targetActorPrincipalId,
83
+ targetClientId,
84
+ op: "host_bash",
85
+ });
86
+ }
53
87
 
54
- HostBashProxy.instance.resolve(requestId, {
88
+ HostBashProxy.instance.resolveResult(requestId, {
55
89
  stdout: stdout ?? "",
56
90
  stderr: stderr ?? "",
57
91
  exitCode: exitCode ?? null,
@@ -84,6 +118,22 @@ export const ROUTES: RouteDefinition[] = [
84
118
  responseBody: z.object({
85
119
  accepted: z.boolean(),
86
120
  }),
121
+ additionalResponses: {
122
+ "400": {
123
+ description:
124
+ "x-vellum-client-id header is missing for a targeted host bash request.",
125
+ },
126
+ "403": {
127
+ description: SAME_ACTOR_FORBIDDEN_DESCRIPTION,
128
+ },
129
+ "404": {
130
+ description: "No pending interaction found for the given requestId.",
131
+ },
132
+ "409": {
133
+ description:
134
+ "Pending interaction exists but is of a different kind (e.g. host_file, host_cu).",
135
+ },
136
+ },
87
137
  handler: handleHostBashResult,
88
138
  },
89
139
  ];
@@ -11,7 +11,8 @@ import {
11
11
  publishCdpEvent,
12
12
  } from "../../browser-session/events.js";
13
13
  import { HostBrowserProxy } from "../../daemon/host-browser-proxy.js";
14
- import { BadRequestError, NotFoundError } from "./errors.js";
14
+ import * as pendingInteractions from "../pending-interactions.js";
15
+ import { BadRequestError, ConflictError, NotFoundError } from "./errors.js";
15
16
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
16
17
 
17
18
  /**
@@ -29,21 +30,26 @@ export type HostBrowserResultResolution =
29
30
  | { ok: true }
30
31
  | {
31
32
  ok: false;
32
- code: "BAD_REQUEST" | "NOT_FOUND";
33
- status: 400 | 404;
33
+ code: "BAD_REQUEST" | "NOT_FOUND" | "CONFLICT";
34
+ status: 400 | 404 | 409;
34
35
  message: string;
35
36
  };
36
37
 
37
38
  /**
38
- * Shared resolver used by both the HTTP route handler and the WS
39
- * `host_browser_result` frame handler. Looks up the pending interaction
40
- * by requestId, validates its kind, and forwards the response to the
41
- * owning conversation.
39
+ * Resolver for the `POST /v1/host-browser-result` HTTP route. Looks up
40
+ * the pending interaction by requestId, validates its kind is
41
+ * `host_browser`, and forwards the response to the owning conversation.
42
+ *
43
+ * NOTE: The WebSocket `host_browser_result` frame path does NOT go
44
+ * through this function — it is handled by `HostBrowserProxy.resolveResult`
45
+ * directly, which only consults `pendingInteractions` and does not
46
+ * currently perform a kind check. That asymmetry is pre-existing; if
47
+ * the WS path is ever opened to less-trusted clients, it should adopt
48
+ * the same kind-check guard added here.
42
49
  *
43
50
  * This function does NOT perform auth — callers are expected to have
44
51
  * already authenticated the caller (the HTTP route uses
45
- * `requireBoundGuardian`, the WS path relies on the JWT check performed
46
- * at WebSocket upgrade time).
52
+ * `requireBoundGuardian`).
47
53
  */
48
54
  export function resolveHostBrowserResultByRequestId(frame: {
49
55
  requestId?: unknown;
@@ -61,20 +67,30 @@ export function resolveHostBrowserResultByRequestId(frame: {
61
67
  };
62
68
  }
63
69
 
64
- const proxy = HostBrowserProxy.instance;
65
- if (!proxy.hasPendingRequest(requestId)) {
70
+ const peeked = pendingInteractions.get(requestId);
71
+ if (!peeked) {
66
72
  return {
67
73
  ok: false,
68
74
  code: "NOT_FOUND",
69
75
  status: 404,
70
- message: "No pending interaction found for this requestId",
76
+ message: "No pending browser request for this requestId",
77
+ };
78
+ }
79
+
80
+ if (peeked.kind !== "host_browser") {
81
+ return {
82
+ ok: false,
83
+ code: "CONFLICT",
84
+ status: 409,
85
+ message: `Pending interaction is of kind "${peeked.kind}", expected "host_browser"`,
71
86
  };
72
87
  }
73
88
 
74
89
  const normalizedContent = typeof content === "string" ? content : "";
75
90
  const normalizedIsError = typeof isError === "boolean" ? isError : false;
76
91
 
77
- proxy.resolve(requestId, {
92
+ const proxy = HostBrowserProxy.instance;
93
+ proxy.resolveResult(requestId, {
78
94
  content: normalizedContent,
79
95
  isError: normalizedIsError,
80
96
  });
@@ -181,6 +197,42 @@ function handleHostBrowserResult({ body }: RouteHandlerArgs) {
181
197
  if (!resolution.ok) {
182
198
  if (resolution.code === "NOT_FOUND")
183
199
  throw new NotFoundError(resolution.message);
200
+ if (resolution.code === "CONFLICT")
201
+ throw new ConflictError(resolution.message);
202
+ throw new BadRequestError(resolution.message);
203
+ }
204
+
205
+ return { accepted: true };
206
+ }
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // POST /v1/host-browser-event
210
+ // ---------------------------------------------------------------------------
211
+
212
+ function handleHostBrowserEvent({ body }: RouteHandlerArgs) {
213
+ if (!body || typeof body !== "object") {
214
+ throw new BadRequestError("Request body is required");
215
+ }
216
+
217
+ const resolution = resolveHostBrowserEvent(body);
218
+ if (!resolution.ok) {
219
+ throw new BadRequestError(resolution.message);
220
+ }
221
+
222
+ return { accepted: true };
223
+ }
224
+
225
+ // ---------------------------------------------------------------------------
226
+ // POST /v1/host-browser-session-invalidated
227
+ // ---------------------------------------------------------------------------
228
+
229
+ function handleHostBrowserSessionInvalidated({ body }: RouteHandlerArgs) {
230
+ if (!body || typeof body !== "object") {
231
+ throw new BadRequestError("Request body is required");
232
+ }
233
+
234
+ const resolution = resolveHostBrowserSessionInvalidated(body);
235
+ if (!resolution.ok) {
184
236
  throw new BadRequestError(resolution.message);
185
237
  }
186
238
 
@@ -210,4 +262,47 @@ export const ROUTES: RouteDefinition[] = [
210
262
  }),
211
263
  handler: handleHostBrowserResult,
212
264
  },
265
+ {
266
+ operationId: "host_browser_event",
267
+ endpoint: "host-browser-event",
268
+ method: "POST",
269
+ requireGuardian: true,
270
+ summary: "Forward a CDP event from the browser extension",
271
+ description:
272
+ "Publishes a chrome.debugger.onEvent firing into the runtime-side browser-session event bus.",
273
+ tags: ["host"],
274
+ requestBody: z.object({
275
+ method: z.string().describe("CDP event method name"),
276
+ params: z.unknown().optional().describe("CDP event parameters"),
277
+ cdpSessionId: z
278
+ .string()
279
+ .optional()
280
+ .describe("CDP session ID (if target-scoped)"),
281
+ }),
282
+ responseBody: z.object({
283
+ accepted: z.boolean(),
284
+ }),
285
+ handler: handleHostBrowserEvent,
286
+ },
287
+ {
288
+ operationId: "host_browser_session_invalidated",
289
+ endpoint: "host-browser-session-invalidated",
290
+ method: "POST",
291
+ requireGuardian: true,
292
+ summary: "Notify runtime that a CDP session was invalidated",
293
+ description:
294
+ "Marks the target as invalidated in the runtime-side browser session registry.",
295
+ tags: ["host"],
296
+ requestBody: z.object({
297
+ targetId: z
298
+ .string()
299
+ .optional()
300
+ .describe("CDP target that was detached"),
301
+ reason: z.string().optional().describe("Detach reason"),
302
+ }),
303
+ responseBody: z.object({
304
+ accepted: z.boolean(),
305
+ }),
306
+ handler: handleHostBrowserSessionInvalidated,
307
+ },
213
308
  ];
@@ -7,10 +7,16 @@
7
7
  import { z } from "zod";
8
8
 
9
9
  import { findConversation } from "../../daemon/conversation-store.js";
10
+ import {
11
+ enforceSameActorOrThrow,
12
+ SAME_ACTOR_FORBIDDEN_DESCRIPTION,
13
+ } from "../auth/same-actor.js";
14
+ import { resolveActorPrincipalIdForLocalGuardian } from "../local-actor-identity.js";
10
15
  import * as pendingInteractions from "../pending-interactions.js";
11
16
  import {
12
17
  BadRequestError,
13
18
  ConflictError,
19
+ ForbiddenError,
14
20
  NotFoundError,
15
21
  } from "./errors.js";
16
22
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
@@ -19,7 +25,7 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
19
25
  // POST /v1/host-cu-result
20
26
  // ---------------------------------------------------------------------------
21
27
 
22
- function handleHostCuResult({ body }: RouteHandlerArgs) {
28
+ function handleHostCuResult({ body, headers }: RouteHandlerArgs) {
23
29
  if (!body || typeof body !== "object") {
24
30
  throw new BadRequestError("Request body is required");
25
31
  }
@@ -58,9 +64,7 @@ function handleHostCuResult({ body }: RouteHandlerArgs) {
58
64
 
59
65
  const peeked = pendingInteractions.get(requestId);
60
66
  if (!peeked) {
61
- throw new NotFoundError(
62
- "No pending interaction found for this requestId",
63
- );
67
+ throw new NotFoundError("No pending interaction found for this requestId");
64
68
  }
65
69
 
66
70
  if (peeked.kind !== "host_cu") {
@@ -69,13 +73,50 @@ function handleHostCuResult({ body }: RouteHandlerArgs) {
69
73
  );
70
74
  }
71
75
 
72
- const interaction = pendingInteractions.resolve(requestId)!;
73
- const conversation = findConversation(interaction.conversationId);
76
+ // Validate submitting client matches the targeted client (if any).
77
+ if (peeked.targetClientId != null) {
78
+ const headerMap = (headers as Record<string, string | undefined>) ?? {};
79
+ const submittingClientId =
80
+ headerMap["x-vellum-client-id"]?.trim() || undefined;
81
+ if (!submittingClientId) {
82
+ throw new BadRequestError(
83
+ "x-vellum-client-id header is missing for a targeted host CU request.",
84
+ );
85
+ }
86
+ if (submittingClientId !== peeked.targetClientId) {
87
+ throw new ForbiddenError(
88
+ `Client "${submittingClientId}" is not the target for this request (expected "${peeked.targetClientId}"). The targeted client must submit the result.`,
89
+ );
90
+ }
91
+
92
+ // Defense-in-depth: require the submitting actor's principal id to match
93
+ // the actor principal id captured when the target client opened its SSE
94
+ // stream. This prevents a different authenticated user with knowledge of
95
+ // both the requestId and target clientId from submitting a result on
96
+ // behalf of the targeted client.
97
+ const submittingActorPrincipalId = resolveActorPrincipalIdForLocalGuardian(
98
+ headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
99
+ );
100
+ enforceSameActorOrThrow({
101
+ sourceActorPrincipalId: submittingActorPrincipalId,
102
+ targetActorPrincipalId: peeked.targetActorPrincipalId,
103
+ targetClientId: peeked.targetClientId,
104
+ op: "host_cu",
105
+ });
106
+ }
107
+
108
+ const conversation = findConversation(peeked.conversationId);
74
109
  if (!conversation) {
110
+ pendingInteractions.resolve(requestId);
75
111
  throw new NotFoundError("Conversation not found for host CU result");
76
112
  }
77
113
 
78
- conversation.hostCuProxy?.resolve(requestId, {
114
+ if (!conversation.hostCuProxy) {
115
+ pendingInteractions.resolve(requestId);
116
+ throw new NotFoundError("No host CU proxy for conversation");
117
+ }
118
+
119
+ conversation.hostCuProxy.processObservation(requestId, {
79
120
  axTree,
80
121
  axDiff,
81
122
  screenshot,
@@ -103,8 +144,7 @@ export const ROUTES: RouteDefinition[] = [
103
144
  method: "POST",
104
145
  requireGuardian: true,
105
146
  summary: "Submit host CU result",
106
- description:
107
- "Resolve a pending host computer-use request by requestId.",
147
+ description: "Resolve a pending host computer-use request by requestId.",
108
148
  tags: ["host"],
109
149
  requestBody: z.object({
110
150
  requestId: z.string().describe("Pending CU request ID"),
@@ -123,6 +163,23 @@ export const ROUTES: RouteDefinition[] = [
123
163
  responseBody: z.object({
124
164
  accepted: z.boolean(),
125
165
  }),
166
+ additionalResponses: {
167
+ "400": {
168
+ description:
169
+ "x-vellum-client-id header is missing for a targeted host CU request.",
170
+ },
171
+ "403": {
172
+ description: SAME_ACTOR_FORBIDDEN_DESCRIPTION,
173
+ },
174
+ "404": {
175
+ description:
176
+ "No pending interaction found for the given requestId, or the conversation/proxy no longer exists.",
177
+ },
178
+ "409": {
179
+ description:
180
+ "Pending interaction exists but is of a different kind (e.g. host_bash, host_file).",
181
+ },
182
+ },
126
183
  handler: handleHostCuResult,
127
184
  },
128
185
  ];
@@ -7,10 +7,16 @@
7
7
  import { z } from "zod";
8
8
 
9
9
  import { HostFileProxy } from "../../daemon/host-file-proxy.js";
10
+ import {
11
+ enforceSameActorOrThrow,
12
+ SAME_ACTOR_FORBIDDEN_DESCRIPTION,
13
+ } from "../auth/same-actor.js";
14
+ import { resolveActorPrincipalIdForLocalGuardian } from "../local-actor-identity.js";
10
15
  import * as pendingInteractions from "../pending-interactions.js";
11
16
  import {
12
17
  BadRequestError,
13
18
  ConflictError,
19
+ ForbiddenError,
14
20
  NotFoundError,
15
21
  } from "./errors.js";
16
22
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
@@ -19,7 +25,7 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
19
25
  // POST /v1/host-file-result
20
26
  // ---------------------------------------------------------------------------
21
27
 
22
- function handleHostFileResult({ body }: RouteHandlerArgs) {
28
+ function handleHostFileResult({ body, headers }: RouteHandlerArgs) {
23
29
  if (!body || typeof body !== "object") {
24
30
  throw new BadRequestError("Request body is required");
25
31
  }
@@ -37,9 +43,7 @@ function handleHostFileResult({ body }: RouteHandlerArgs) {
37
43
 
38
44
  const peeked = pendingInteractions.get(requestId);
39
45
  if (!peeked) {
40
- throw new NotFoundError(
41
- "No pending interaction found for this requestId",
42
- );
46
+ throw new NotFoundError("No pending interaction found for this requestId");
43
47
  }
44
48
 
45
49
  if (peeked.kind !== "host_file") {
@@ -48,7 +52,36 @@ function handleHostFileResult({ body }: RouteHandlerArgs) {
48
52
  );
49
53
  }
50
54
 
51
- pendingInteractions.resolve(requestId);
55
+ // Validate submitting client matches the targeted client (if any).
56
+ if (peeked.targetClientId != null) {
57
+ const headerMap = (headers as Record<string, string | undefined>) ?? {};
58
+ const submittingClientId =
59
+ headerMap["x-vellum-client-id"]?.trim() || undefined;
60
+ if (!submittingClientId) {
61
+ throw new BadRequestError(
62
+ "x-vellum-client-id header is missing for a targeted host file request.",
63
+ );
64
+ }
65
+ if (submittingClientId !== peeked.targetClientId) {
66
+ throw new ForbiddenError(
67
+ `Client "${submittingClientId}" is not the target for this request (expected "${peeked.targetClientId}"). The targeted client must submit the result.`,
68
+ );
69
+ }
70
+
71
+ // Defense-in-depth: also require the submitting actor's principal id to
72
+ // match the actor that opened the target client's SSE stream. This blocks
73
+ // cross-user submissions even if a different user somehow obtains the
74
+ // target client id.
75
+ const submittingActorPrincipalId = resolveActorPrincipalIdForLocalGuardian(
76
+ headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
77
+ );
78
+ enforceSameActorOrThrow({
79
+ sourceActorPrincipalId: submittingActorPrincipalId,
80
+ targetActorPrincipalId: peeked.targetActorPrincipalId,
81
+ targetClientId: peeked.targetClientId,
82
+ op: "host_file",
83
+ });
84
+ }
52
85
 
53
86
  HostFileProxy.instance.resolve(requestId, {
54
87
  content: content ?? "",
@@ -90,6 +123,22 @@ export const ROUTES: RouteDefinition[] = [
90
123
  responseBody: z.object({
91
124
  accepted: z.boolean(),
92
125
  }),
126
+ additionalResponses: {
127
+ "400": {
128
+ description:
129
+ "x-vellum-client-id header is missing for a targeted host file request.",
130
+ },
131
+ "403": {
132
+ description: SAME_ACTOR_FORBIDDEN_DESCRIPTION,
133
+ },
134
+ "404": {
135
+ description: "No pending interaction found for the given requestId.",
136
+ },
137
+ "409": {
138
+ description:
139
+ "Pending interaction exists but is of a different kind (e.g. host_bash, host_cu).",
140
+ },
141
+ },
93
142
  handler: handleHostFileResult,
94
143
  },
95
144
  ];