@vellumai/assistant 0.4.46 → 0.4.49

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 (382) hide show
  1. package/ARCHITECTURE.md +7 -7
  2. package/README.md +2 -23
  3. package/docs/architecture/integrations.md +45 -41
  4. package/docs/architecture/keychain-broker.md +3 -3
  5. package/docs/architecture/security.md +5 -5
  6. package/docs/runbook-trusted-contacts.md +3 -8
  7. package/hook-templates/debug-prompt-logger/hook.json +1 -1
  8. package/hook-templates/debug-prompt-logger/run.sh +1 -3
  9. package/package.json +1 -1
  10. package/src/__tests__/actor-token-service.test.ts +0 -1
  11. package/src/__tests__/anthropic-provider.test.ts +156 -0
  12. package/src/__tests__/approval-cascade.test.ts +810 -0
  13. package/src/__tests__/approval-primitive.test.ts +0 -1
  14. package/src/__tests__/approval-routes-http.test.ts +2 -0
  15. package/src/__tests__/assistant-attachments.test.ts +12 -34
  16. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
  17. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
  18. package/src/__tests__/browser-fill-credential.test.ts +5 -2
  19. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  20. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
  21. package/src/__tests__/channel-guardian.test.ts +0 -2
  22. package/src/__tests__/channel-readiness-routes.test.ts +35 -25
  23. package/src/__tests__/channel-readiness-service.test.ts +10 -9
  24. package/src/__tests__/checker.test.ts +9 -29
  25. package/src/__tests__/cli.test.ts +23 -0
  26. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
  27. package/src/__tests__/computer-use-tools.test.ts +2 -19
  28. package/src/__tests__/config-watcher.test.ts +0 -1
  29. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  30. package/src/__tests__/context-image-dimensions.test.ts +332 -0
  31. package/src/__tests__/context-token-estimator.test.ts +196 -13
  32. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  33. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  34. package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
  35. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  36. package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
  37. package/src/__tests__/credential-broker-server-use.test.ts +22 -21
  38. package/src/__tests__/credential-broker.test.ts +2 -1
  39. package/src/__tests__/credential-metadata-store.test.ts +239 -26
  40. package/src/__tests__/credential-resolve.test.ts +5 -4
  41. package/src/__tests__/credential-security-e2e.test.ts +8 -8
  42. package/src/__tests__/credential-security-invariants.test.ts +111 -7
  43. package/src/__tests__/credential-vault-unit.test.ts +287 -54
  44. package/src/__tests__/credential-vault.test.ts +406 -12
  45. package/src/__tests__/credentials-cli.test.ts +82 -6
  46. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  47. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  48. package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
  49. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  50. package/src/__tests__/gemini-image-service.test.ts +75 -45
  51. package/src/__tests__/gemini-provider.test.ts +9 -6
  52. package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
  53. package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
  54. package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
  55. package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
  56. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  57. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  58. package/src/__tests__/guardian-grant-minting.test.ts +35 -0
  59. package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
  60. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  61. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
  62. package/src/__tests__/heartbeat-service.test.ts +0 -1
  63. package/src/__tests__/host-cu-proxy.test.ts +629 -0
  64. package/src/__tests__/host-shell-tool.test.ts +27 -15
  65. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  66. package/src/__tests__/ingress-url-consistency.test.ts +14 -21
  67. package/src/__tests__/integration-status.test.ts +38 -25
  68. package/src/__tests__/intent-routing.test.ts +0 -1
  69. package/src/__tests__/invite-routes-http.test.ts +10 -9
  70. package/src/__tests__/keychain-broker-client.test.ts +11 -43
  71. package/src/__tests__/managed-proxy-context.test.ts +5 -3
  72. package/src/__tests__/media-generate-image.test.ts +63 -2
  73. package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
  74. package/src/__tests__/messaging-send-tool.test.ts +4 -6
  75. package/src/__tests__/notification-routing-intent.test.ts +0 -1
  76. package/src/__tests__/oauth-cli.test.ts +373 -14
  77. package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
  78. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  79. package/src/__tests__/oauth-store.test.ts +756 -0
  80. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  81. package/src/__tests__/provider-error-scenarios.test.ts +0 -1
  82. package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
  83. package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
  84. package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
  85. package/src/__tests__/public-ingress-urls.test.ts +15 -21
  86. package/src/__tests__/recording-handler.test.ts +3 -4
  87. package/src/__tests__/registry.test.ts +2 -2
  88. package/src/__tests__/runtime-events-sse.test.ts +55 -7
  89. package/src/__tests__/schedule-store.test.ts +0 -1
  90. package/src/__tests__/scheduler-recurrence.test.ts +0 -1
  91. package/src/__tests__/schema-transforms.test.ts +226 -0
  92. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  93. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  94. package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
  95. package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
  96. package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
  97. package/src/__tests__/secret-ingress-handler.test.ts +0 -1
  98. package/src/__tests__/secret-onetime-send.test.ts +5 -3
  99. package/src/__tests__/send-endpoint-busy.test.ts +21 -6
  100. package/src/__tests__/sequence-store.test.ts +0 -1
  101. package/src/__tests__/session-init.benchmark.test.ts +4 -5
  102. package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
  103. package/src/__tests__/skill-include-graph.test.ts +66 -0
  104. package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
  105. package/src/__tests__/skill-load-tool.test.ts +149 -1
  106. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
  107. package/src/__tests__/skills-uninstall.test.ts +3 -3
  108. package/src/__tests__/skills.test.ts +3 -12
  109. package/src/__tests__/slack-channel-config.test.ts +76 -11
  110. package/src/__tests__/slack-share-routes.test.ts +17 -14
  111. package/src/__tests__/system-prompt.test.ts +0 -1
  112. package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
  113. package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
  114. package/src/__tests__/terminal-tools.test.ts +4 -3
  115. package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
  116. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  117. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  118. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  119. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
  120. package/src/__tests__/tool-executor.test.ts +0 -1
  121. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  122. package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
  123. package/src/__tests__/trust-store.test.ts +1 -22
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  126. package/src/__tests__/twilio-config.test.ts +2 -1
  127. package/src/__tests__/twilio-provider.test.ts +4 -2
  128. package/src/__tests__/twilio-routes.test.ts +5 -20
  129. package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
  130. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  131. package/src/agent/ax-tree-compaction.test.ts +235 -0
  132. package/src/agent/loop.ts +76 -130
  133. package/src/calls/call-domain.ts +8 -10
  134. package/src/calls/relay-server.ts +9 -13
  135. package/src/calls/twilio-config.ts +4 -8
  136. package/src/calls/twilio-provider.ts +2 -1
  137. package/src/calls/twilio-rest.ts +2 -1
  138. package/src/calls/twilio-routes.ts +1 -2
  139. package/src/calls/voice-ingress-preflight.ts +1 -1
  140. package/src/cli/commands/browser-relay.ts +46 -15
  141. package/src/cli/commands/completions.ts +0 -3
  142. package/src/cli/commands/credentials.ts +110 -23
  143. package/src/cli/commands/oauth/apps.ts +255 -0
  144. package/src/cli/commands/oauth/connections.ts +299 -0
  145. package/src/cli/commands/oauth/index.ts +52 -0
  146. package/src/cli/commands/oauth/providers.ts +242 -0
  147. package/src/cli/commands/skills.ts +4 -338
  148. package/src/cli/program.ts +1 -5
  149. package/src/cli/reference.ts +1 -3
  150. package/src/cli.ts +3 -2
  151. package/src/config/assistant-feature-flags.ts +0 -3
  152. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  153. package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
  154. package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
  155. package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
  156. package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
  157. package/src/config/bundled-skills/gmail/SKILL.md +4 -4
  158. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
  159. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
  160. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
  161. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
  162. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
  163. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
  164. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
  165. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
  166. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
  167. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
  168. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
  169. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
  170. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
  171. package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
  172. package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
  173. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
  174. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
  175. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
  176. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
  177. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
  178. package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
  179. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
  180. package/src/config/bundled-skills/messaging/SKILL.md +6 -6
  181. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
  182. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
  183. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
  184. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
  185. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
  186. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
  187. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
  188. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
  189. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
  190. package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
  191. package/src/config/bundled-skills/settings/SKILL.md +1 -1
  192. package/src/config/bundled-skills/settings/TOOLS.json +2 -8
  193. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
  194. package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
  195. package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
  196. package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
  197. package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
  198. package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
  199. package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
  200. package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
  201. package/src/config/env-registry.ts +14 -83
  202. package/src/config/env.ts +11 -50
  203. package/src/config/feature-flag-registry.json +16 -16
  204. package/src/config/schema.ts +3 -1
  205. package/src/config/skills.ts +21 -2
  206. package/src/context/image-dimensions.ts +229 -0
  207. package/src/context/token-estimator.ts +75 -12
  208. package/src/context/window-manager.ts +49 -10
  209. package/src/daemon/assistant-attachments.ts +1 -13
  210. package/src/daemon/guardian-action-generators.ts +4 -5
  211. package/src/daemon/handlers/config-ingress.ts +8 -33
  212. package/src/daemon/handlers/config-slack-channel.ts +76 -56
  213. package/src/daemon/handlers/config-telegram.ts +53 -24
  214. package/src/daemon/handlers/sessions.ts +10 -24
  215. package/src/daemon/handlers/shared.ts +0 -130
  216. package/src/daemon/host-cu-proxy.ts +401 -0
  217. package/src/daemon/lifecycle.ts +39 -63
  218. package/src/daemon/message-protocol.ts +3 -0
  219. package/src/daemon/message-types/computer-use.ts +2 -119
  220. package/src/daemon/message-types/host-cu.ts +19 -0
  221. package/src/daemon/message-types/integrations.ts +1 -0
  222. package/src/daemon/message-types/messages.ts +3 -0
  223. package/src/daemon/server.ts +14 -21
  224. package/src/daemon/session-agent-loop-handlers.ts +2 -0
  225. package/src/daemon/session-attachments.ts +1 -2
  226. package/src/daemon/session-messaging.ts +3 -1
  227. package/src/daemon/session-slash.ts +1 -1
  228. package/src/daemon/session-surfaces.ts +40 -28
  229. package/src/daemon/session-tool-setup.ts +20 -11
  230. package/src/daemon/session.ts +139 -16
  231. package/src/daemon/tool-side-effects.ts +2 -8
  232. package/src/daemon/watch-handler.ts +2 -2
  233. package/src/email/providers/index.ts +2 -1
  234. package/src/events/tool-metrics-listener.ts +2 -2
  235. package/src/hooks/manager.ts +1 -4
  236. package/src/inbound/public-ingress-urls.ts +7 -7
  237. package/src/instrument.ts +15 -1
  238. package/src/logfire.ts +16 -5
  239. package/src/media/app-icon-generator.ts +30 -4
  240. package/src/media/avatar-router.ts +26 -3
  241. package/src/media/gemini-image-service.ts +28 -2
  242. package/src/memory/conversation-key-store.ts +21 -0
  243. package/src/memory/db-init.ts +4 -0
  244. package/src/memory/guardian-action-store.ts +1 -1
  245. package/src/memory/migrations/149-oauth-tables.ts +60 -0
  246. package/src/memory/migrations/index.ts +1 -0
  247. package/src/memory/schema/guardian.ts +1 -1
  248. package/src/memory/schema/index.ts +1 -0
  249. package/src/memory/schema/oauth.ts +65 -0
  250. package/src/messaging/provider.ts +19 -13
  251. package/src/messaging/providers/gmail/adapter.ts +40 -23
  252. package/src/messaging/providers/gmail/client.ts +283 -122
  253. package/src/messaging/providers/gmail/people-client.ts +32 -24
  254. package/src/messaging/providers/slack/adapter.ts +29 -19
  255. package/src/messaging/providers/slack/client.ts +265 -78
  256. package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
  257. package/src/messaging/providers/whatsapp/adapter.ts +17 -11
  258. package/src/messaging/registry.ts +2 -31
  259. package/src/notifications/copy-composer.ts +0 -5
  260. package/src/notifications/signal.ts +4 -5
  261. package/src/oauth/byo-connection.test.ts +537 -0
  262. package/src/oauth/byo-connection.ts +128 -0
  263. package/src/oauth/connect-orchestrator.ts +139 -56
  264. package/src/oauth/connect-types.ts +17 -23
  265. package/src/oauth/connection-resolver.ts +58 -0
  266. package/src/oauth/connection.ts +38 -0
  267. package/src/oauth/manual-token-connection.ts +104 -0
  268. package/src/oauth/oauth-store.ts +496 -0
  269. package/src/oauth/platform-connection.test.ts +192 -0
  270. package/src/oauth/platform-connection.ts +111 -0
  271. package/src/oauth/provider-behaviors.ts +124 -0
  272. package/src/oauth/scope-policy.ts +9 -2
  273. package/src/oauth/seed-providers.ts +161 -0
  274. package/src/oauth/token-persistence.ts +74 -78
  275. package/src/permissions/checker.ts +8 -4
  276. package/src/permissions/defaults.ts +0 -1
  277. package/src/permissions/prompter.ts +10 -1
  278. package/src/permissions/trust-store.ts +13 -0
  279. package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
  280. package/src/prompts/system-prompt.ts +70 -45
  281. package/src/providers/anthropic/client.ts +133 -24
  282. package/src/providers/gemini/client.ts +15 -6
  283. package/src/providers/managed-proxy/constants.ts +2 -2
  284. package/src/providers/managed-proxy/context.ts +5 -1
  285. package/src/providers/ratelimit.ts +17 -0
  286. package/src/providers/registry.ts +2 -2
  287. package/src/providers/retry.ts +1 -27
  288. package/src/runtime/AGENTS.md +17 -0
  289. package/src/runtime/auth/route-policy.ts +0 -3
  290. package/src/runtime/channel-invite-transports/telegram.ts +2 -1
  291. package/src/runtime/channel-readiness-service.ts +168 -195
  292. package/src/runtime/channel-readiness-types.ts +4 -0
  293. package/src/runtime/channel-reply-delivery.ts +0 -40
  294. package/src/runtime/gateway-client.ts +0 -7
  295. package/src/runtime/guardian-action-conversation-turn.ts +1 -3
  296. package/src/runtime/guardian-action-followup-executor.ts +1 -1
  297. package/src/runtime/guardian-action-message-composer.ts +3 -23
  298. package/src/runtime/http-server.ts +17 -10
  299. package/src/runtime/http-types.ts +2 -3
  300. package/src/runtime/middleware/rate-limiter.ts +74 -20
  301. package/src/runtime/middleware/twilio-validation.ts +1 -11
  302. package/src/runtime/pending-interactions.ts +14 -12
  303. package/src/runtime/routes/channel-delivery-routes.ts +0 -1
  304. package/src/runtime/routes/channel-readiness-routes.ts +2 -0
  305. package/src/runtime/routes/conversation-routes.ts +73 -19
  306. package/src/runtime/routes/diagnostics-routes.ts +11 -9
  307. package/src/runtime/routes/events-routes.ts +21 -11
  308. package/src/runtime/routes/guardian-approval-interception.ts +20 -5
  309. package/src/runtime/routes/host-cu-routes.ts +97 -0
  310. package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
  311. package/src/runtime/routes/integrations/slack/share.ts +6 -6
  312. package/src/runtime/routes/integrations/twilio.ts +6 -5
  313. package/src/runtime/routes/log-export-routes.ts +126 -8
  314. package/src/runtime/routes/secret-routes.ts +3 -2
  315. package/src/runtime/routes/settings-routes.ts +113 -48
  316. package/src/runtime/routes/surface-action-routes.ts +1 -1
  317. package/src/runtime/routes/watch-routes.ts +128 -0
  318. package/src/schedule/integration-status.ts +10 -8
  319. package/src/security/credential-key.ts +14 -0
  320. package/src/security/keychain-broker-client.ts +5 -6
  321. package/src/security/oauth2.ts +1 -1
  322. package/src/security/token-manager.ts +145 -43
  323. package/src/skills/catalog-install.ts +358 -0
  324. package/src/skills/include-graph.ts +32 -0
  325. package/src/telegram/bot-username.ts +2 -3
  326. package/src/tools/apps/definitions.ts +0 -5
  327. package/src/tools/assets/materialize.ts +0 -5
  328. package/src/tools/assets/search.ts +0 -5
  329. package/src/tools/browser/headless-browser.ts +1 -67
  330. package/src/tools/browser/network-recorder.ts +1 -1
  331. package/src/tools/browser/network-recording-types.ts +1 -1
  332. package/src/tools/claude-code/claude-code.ts +0 -5
  333. package/src/tools/computer-use/definitions.ts +46 -11
  334. package/src/tools/computer-use/registry.ts +4 -5
  335. package/src/tools/credentials/broker.ts +5 -4
  336. package/src/tools/credentials/metadata-store.ts +22 -74
  337. package/src/tools/credentials/resolve.ts +2 -1
  338. package/src/tools/credentials/vault.ts +139 -151
  339. package/src/tools/filesystem/edit.ts +1 -6
  340. package/src/tools/filesystem/read.ts +0 -5
  341. package/src/tools/filesystem/write.ts +1 -6
  342. package/src/tools/host-filesystem/edit.ts +1 -6
  343. package/src/tools/host-filesystem/read.ts +1 -6
  344. package/src/tools/host-filesystem/write.ts +1 -6
  345. package/src/tools/mcp/mcp-tool-factory.ts +18 -1
  346. package/src/tools/memory/definitions.ts +0 -5
  347. package/src/tools/network/web-fetch.ts +0 -5
  348. package/src/tools/network/web-search.ts +0 -5
  349. package/src/tools/registry.ts +2 -7
  350. package/src/tools/schema-transforms.ts +99 -0
  351. package/src/tools/skills/load.ts +62 -8
  352. package/src/tools/swarm/delegate.ts +0 -5
  353. package/src/tools/system/avatar-generator.ts +0 -5
  354. package/src/tools/ui-surface/definitions.ts +0 -15
  355. package/src/tools/watch/screen-watch.ts +0 -5
  356. package/src/tools/watch/watch-state.ts +0 -12
  357. package/src/util/logger.ts +7 -41
  358. package/src/util/platform.ts +9 -28
  359. package/src/version.ts +10 -0
  360. package/src/watcher/providers/github.ts +51 -52
  361. package/src/watcher/providers/gmail.ts +88 -80
  362. package/src/watcher/providers/google-calendar.ts +94 -86
  363. package/src/watcher/providers/linear.ts +87 -93
  364. package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
  365. package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
  366. package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
  367. package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
  368. package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
  369. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
  370. package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
  371. package/src/cli/commands/dev.ts +0 -129
  372. package/src/cli/commands/map.ts +0 -391
  373. package/src/cli/commands/oauth.ts +0 -77
  374. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
  375. package/src/daemon/computer-use-session.ts +0 -1020
  376. package/src/daemon/ride-shotgun-handler.ts +0 -567
  377. package/src/oauth/provider-profiles.ts +0 -192
  378. package/src/prompts/computer-use-prompt.ts +0 -98
  379. package/src/runtime/routes/computer-use-routes.ts +0 -641
  380. package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
  381. package/src/runtime/telegram-streaming-delivery.ts +0 -383
  382. package/src/tools/computer-use/request-computer-control.ts +0 -61
@@ -1,641 +0,0 @@
1
- /**
2
- * HTTP route handlers for computer use session lifecycle.
3
- *
4
- * These endpoints expose CU session management, ride-shotgun, and watch
5
- * observation functionality over HTTP.
6
- *
7
- * All CU write operations require the `chat.write` scope.
8
- */
9
-
10
- import { getConfig } from "../../config/loader.js";
11
- import type { ComputerUseSession } from "../../daemon/computer-use-session.js";
12
- import type { CuObservation } from "../../daemon/message-protocol.js";
13
- import type { ServerMessage } from "../../daemon/message-protocol.js";
14
- import { RateLimitProvider } from "../../providers/ratelimit.js";
15
- import { getFailoverProvider } from "../../providers/registry.js";
16
- import { getLogger } from "../../util/logger.js";
17
- import { buildAssistantEvent } from "../assistant-event.js";
18
- import { assistantEventHub } from "../assistant-event-hub.js";
19
- import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
20
- import { httpError } from "../http-errors.js";
21
- import type { RouteDefinition } from "../http-router.js";
22
-
23
- const log = getLogger("computer-use-routes");
24
-
25
- // ---------------------------------------------------------------------------
26
- // Dependency injection interface
27
- // ---------------------------------------------------------------------------
28
-
29
- /**
30
- * Minimal interface for CU session management.
31
- * The daemon wires a concrete implementation at startup.
32
- */
33
- export interface ComputerUseDeps {
34
- /** Active CU sessions keyed by session ID. */
35
- cuSessions: Map<string, ComputerUseSession>;
36
- /** Shared rate-limiter timestamps across the daemon. */
37
- sharedRequestTimestamps: number[];
38
- /** Sequence tracker for CU observations (per session). */
39
- cuObservationParseSequence: Map<string, number>;
40
- /** Handle a ride-shotgun start request. Returns watchId and sessionId. */
41
- handleRideShotgunStart: (params: {
42
- durationSeconds: number;
43
- intervalSeconds: number;
44
- mode?: "observe" | "learn";
45
- targetDomain?: string;
46
- navigateDomain?: string;
47
- autoNavigate?: boolean;
48
- }) => Promise<{ watchId: string; sessionId: string }>;
49
- /** Handle a ride-shotgun stop request. */
50
- handleRideShotgunStop: (watchId: string) => Promise<void>;
51
- /** Get ride-shotgun session status by watchId. */
52
- getRideShotgunStatus: (watchId: string) =>
53
- | {
54
- status: "active" | "completing" | "completed" | "cancelled";
55
- sessionId: string;
56
- recordingId?: string;
57
- savedRecordingPath?: string;
58
- bootstrapFailureReason?: string;
59
- }
60
- | undefined;
61
- /** Handle a watch observation. */
62
- handleWatchObservation: (params: {
63
- watchId: string;
64
- sessionId: string;
65
- ocrText: string;
66
- appName?: string;
67
- windowTitle?: string;
68
- bundleIdentifier?: string;
69
- timestamp: number;
70
- captureIndex: number;
71
- totalExpected: number;
72
- }) => Promise<void>;
73
- }
74
-
75
- // ---------------------------------------------------------------------------
76
- // Helpers
77
- // ---------------------------------------------------------------------------
78
-
79
- /** Publish a server message to the SSE event hub for HTTP clients. */
80
- function publishEvent(msg: ServerMessage, sessionId?: string): void {
81
- void assistantEventHub.publish(
82
- buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, msg, sessionId),
83
- );
84
- }
85
-
86
- function removeCuSessionReferences(
87
- deps: ComputerUseDeps,
88
- sessionId: string,
89
- expectedSession?: ComputerUseSession,
90
- ): void {
91
- const current = deps.cuSessions.get(sessionId);
92
- if (expectedSession && current && current !== expectedSession) {
93
- return;
94
- }
95
- deps.cuSessions.delete(sessionId);
96
- deps.cuObservationParseSequence.delete(sessionId);
97
- }
98
-
99
- // ---------------------------------------------------------------------------
100
- // Route handlers
101
- // ---------------------------------------------------------------------------
102
-
103
- /**
104
- * POST /v1/computer-use/sessions — create a CU session.
105
- *
106
- * Body: { sessionId, task, screenWidth, screenHeight, interactionType? }
107
- */
108
- async function handleCreateSession(
109
- req: Request,
110
- deps: ComputerUseDeps,
111
- ): Promise<Response> {
112
- const body = (await req.json()) as {
113
- sessionId?: string;
114
- task?: string;
115
- screenWidth?: number;
116
- screenHeight?: number;
117
- interactionType?: "computer_use" | "text_qa";
118
- };
119
-
120
- const { sessionId, task, screenWidth, screenHeight, interactionType } = body;
121
-
122
- if (!sessionId || typeof sessionId !== "string") {
123
- return httpError("BAD_REQUEST", "sessionId is required", 400);
124
- }
125
- if (!task || typeof task !== "string") {
126
- return httpError("BAD_REQUEST", "task is required", 400);
127
- }
128
- if (typeof screenWidth !== "number" || screenWidth <= 0) {
129
- return httpError(
130
- "BAD_REQUEST",
131
- "screenWidth must be a positive number",
132
- 400,
133
- );
134
- }
135
- if (typeof screenHeight !== "number" || screenHeight <= 0) {
136
- return httpError(
137
- "BAD_REQUEST",
138
- "screenHeight must be a positive number",
139
- 400,
140
- );
141
- }
142
-
143
- // Abort any existing session with the same ID to prevent zombies
144
- const existingSession = deps.cuSessions.get(sessionId);
145
- if (existingSession) {
146
- existingSession.abort();
147
- removeCuSessionReferences(deps, sessionId, existingSession);
148
- }
149
-
150
- const config = getConfig();
151
- let provider = getFailoverProvider(config.provider, config.providerOrder);
152
- const { rateLimit } = config;
153
- if (rateLimit.maxRequestsPerMinute > 0 || rateLimit.maxTokensPerSession > 0) {
154
- provider = new RateLimitProvider(
155
- provider,
156
- rateLimit,
157
- deps.sharedRequestTimestamps,
158
- );
159
- }
160
-
161
- const sendToClient = (serverMsg: ServerMessage) => {
162
- publishEvent(serverMsg, sessionId);
163
- };
164
-
165
- const sessionRef: { current?: ComputerUseSession } = {};
166
- const onTerminal = (sid: string) => {
167
- removeCuSessionReferences(deps, sid, sessionRef.current);
168
- log.info(
169
- { sessionId: sid },
170
- "Computer-use session cleaned up after terminal state",
171
- );
172
- };
173
-
174
- // Dynamic import to avoid circular dependency
175
- const { ComputerUseSession: CUSession } =
176
- await import("../../daemon/computer-use-session.js");
177
-
178
- const session = new CUSession(
179
- sessionId,
180
- task,
181
- screenWidth,
182
- screenHeight,
183
- provider,
184
- sendToClient,
185
- interactionType,
186
- onTerminal,
187
- );
188
- sessionRef.current = session;
189
-
190
- deps.cuSessions.set(sessionId, session);
191
-
192
- log.info(
193
- { sessionId, taskLength: task.length },
194
- "Computer-use session created via HTTP",
195
- );
196
-
197
- return Response.json({ sessionId }, { status: 201 });
198
- }
199
-
200
- /**
201
- * POST /v1/computer-use/sessions/:id/abort — abort a CU session.
202
- */
203
- function handleAbortSession(
204
- sessionId: string,
205
- deps: ComputerUseDeps,
206
- ): Response {
207
- const session = deps.cuSessions.get(sessionId);
208
- if (!session) {
209
- log.debug(
210
- { sessionId },
211
- "CU session abort via HTTP: session not found (already finished?)",
212
- );
213
- return httpError("NOT_FOUND", "Session not found", 404);
214
- }
215
-
216
- session.abort();
217
- removeCuSessionReferences(deps, sessionId, session);
218
-
219
- log.info({ sessionId }, "Computer-use session aborted via HTTP");
220
- return Response.json({ ok: true });
221
- }
222
-
223
- /**
224
- * POST /v1/computer-use/observations — send a CU observation.
225
- *
226
- * Body: { sessionId, axTree?, axDiff?, secondaryWindows?, screenshot?,
227
- * screenshotWidthPx?, screenshotHeightPx?, screenWidthPt?,
228
- * screenHeightPt?, coordinateOrigin?, captureDisplayId?,
229
- * executionResult?, executionError?, userGuidance? }
230
- */
231
- async function handleObservation(
232
- req: Request,
233
- deps: ComputerUseDeps,
234
- ): Promise<Response> {
235
- const receiveTimestampMs = Date.now();
236
- const msg = (await req.json()) as CuObservation;
237
-
238
- if (!msg.sessionId || typeof msg.sessionId !== "string") {
239
- return httpError("BAD_REQUEST", "sessionId is required", 400);
240
- }
241
-
242
- // HTTP observations arrive with inline data (no blob refs to hydrate).
243
- // Use the shared deps-injected sequence map as the single source of truth.
244
- const previousSequence =
245
- deps.cuObservationParseSequence.get(msg.sessionId) ?? 0;
246
- const sequence = previousSequence + 1;
247
- deps.cuObservationParseSequence.set(msg.sessionId, sequence);
248
-
249
- const axTreeBytes = msg.axTree ? Buffer.byteLength(msg.axTree, "utf8") : 0;
250
- const axDiffBytes = msg.axDiff ? Buffer.byteLength(msg.axDiff, "utf8") : 0;
251
- const secondaryWindowsBytes = msg.secondaryWindows
252
- ? Buffer.byteLength(msg.secondaryWindows, "utf8")
253
- : 0;
254
- const screenshotBase64Bytes = msg.screenshot
255
- ? Buffer.byteLength(msg.screenshot, "utf8")
256
- : 0;
257
- const screenshotApproxRawBytes = msg.screenshot
258
- ? Math.floor((msg.screenshot.length / 4) * 3)
259
- : 0;
260
-
261
- log.info(
262
- {
263
- sessionId: msg.sessionId,
264
- sequence,
265
- receiveTimestampMs,
266
- axTreeBytes,
267
- axDiffBytes,
268
- secondaryWindowsBytes,
269
- screenshotBase64Bytes,
270
- screenshotApproxRawBytes,
271
- },
272
- "HTTP_METRIC cu_observation_http_receive",
273
- );
274
-
275
- const session = deps.cuSessions.get(msg.sessionId);
276
- if (!session) {
277
- publishEvent(
278
- {
279
- type: "cu_error",
280
- sessionId: msg.sessionId,
281
- message: `No computer-use session found for id ${msg.sessionId}`,
282
- },
283
- msg.sessionId,
284
- );
285
- return httpError(
286
- "NOT_FOUND",
287
- `No computer-use session found for id ${msg.sessionId}`,
288
- 404,
289
- );
290
- }
291
-
292
- // Fire-and-forget: the session sends messages via its sendToClient callback
293
- session.handleObservation(msg).catch((err) => {
294
- log.error(
295
- { err, sessionId: msg.sessionId },
296
- "Error handling CU observation (HTTP)",
297
- );
298
- });
299
-
300
- return Response.json({ ok: true, sequence });
301
- }
302
-
303
- /**
304
- * POST /v1/computer-use/tasks — submit a task.
305
- *
306
- * This is a simplified HTTP version of task_submit that creates a CU session.
307
- * This endpoint provides direct CU session creation.
308
- *
309
- * Body: { task, screenWidth, screenHeight, interactionType? }
310
- */
311
- async function handleTaskSubmit(
312
- req: Request,
313
- deps: ComputerUseDeps,
314
- ): Promise<Response> {
315
- const body = (await req.json()) as {
316
- task?: string;
317
- screenWidth?: number;
318
- screenHeight?: number;
319
- interactionType?: "computer_use" | "text_qa";
320
- };
321
-
322
- const { task, screenWidth, screenHeight, interactionType } = body;
323
-
324
- if (!task || typeof task !== "string") {
325
- return httpError("BAD_REQUEST", "task is required", 400);
326
- }
327
- if (typeof screenWidth !== "number" || screenWidth <= 0) {
328
- return httpError(
329
- "BAD_REQUEST",
330
- "screenWidth must be a positive number",
331
- 400,
332
- );
333
- }
334
- if (typeof screenHeight !== "number" || screenHeight <= 0) {
335
- return httpError(
336
- "BAD_REQUEST",
337
- "screenHeight must be a positive number",
338
- 400,
339
- );
340
- }
341
-
342
- const sessionId = crypto.randomUUID();
343
-
344
- // Reuse session creation logic
345
- const config = getConfig();
346
- let provider = getFailoverProvider(config.provider, config.providerOrder);
347
- const { rateLimit } = config;
348
- if (rateLimit.maxRequestsPerMinute > 0 || rateLimit.maxTokensPerSession > 0) {
349
- provider = new RateLimitProvider(
350
- provider,
351
- rateLimit,
352
- deps.sharedRequestTimestamps,
353
- );
354
- }
355
-
356
- const sendToClient = (serverMsg: ServerMessage) => {
357
- publishEvent(serverMsg, sessionId);
358
- };
359
-
360
- const sessionRef: { current?: ComputerUseSession } = {};
361
- const onTerminal = (sid: string) => {
362
- removeCuSessionReferences(deps, sid, sessionRef.current);
363
- log.info(
364
- { sessionId: sid },
365
- "Computer-use session cleaned up after terminal state",
366
- );
367
- };
368
-
369
- const { ComputerUseSession: CUSession } =
370
- await import("../../daemon/computer-use-session.js");
371
-
372
- const session = new CUSession(
373
- sessionId,
374
- task,
375
- screenWidth,
376
- screenHeight,
377
- provider,
378
- sendToClient,
379
- interactionType,
380
- onTerminal,
381
- );
382
- sessionRef.current = session;
383
-
384
- deps.cuSessions.set(sessionId, session);
385
-
386
- log.info(
387
- { sessionId, taskLength: task.length },
388
- "Task submitted via HTTP — CU session created",
389
- );
390
-
391
- return Response.json(
392
- { sessionId, interactionType: interactionType ?? "computer_use" },
393
- { status: 201 },
394
- );
395
- }
396
-
397
- /**
398
- * POST /v1/computer-use/ride-shotgun/start — start a ride-shotgun session.
399
- *
400
- * Body: { durationSeconds, intervalSeconds, mode?, targetDomain?, navigateDomain?, autoNavigate? }
401
- */
402
- async function handleRideShotgunStartRoute(
403
- req: Request,
404
- deps: ComputerUseDeps,
405
- ): Promise<Response> {
406
- const body = (await req.json()) as {
407
- durationSeconds?: number;
408
- intervalSeconds?: number;
409
- mode?: "observe" | "learn";
410
- targetDomain?: string;
411
- navigateDomain?: string;
412
- autoNavigate?: boolean;
413
- };
414
-
415
- const {
416
- durationSeconds,
417
- intervalSeconds,
418
- mode,
419
- targetDomain,
420
- navigateDomain,
421
- autoNavigate,
422
- } = body;
423
-
424
- if (typeof durationSeconds !== "number" || durationSeconds <= 0) {
425
- return httpError(
426
- "BAD_REQUEST",
427
- "durationSeconds must be a positive number",
428
- 400,
429
- );
430
- }
431
- if (typeof intervalSeconds !== "number" || intervalSeconds <= 0) {
432
- return httpError(
433
- "BAD_REQUEST",
434
- "intervalSeconds must be a positive number",
435
- 400,
436
- );
437
- }
438
-
439
- try {
440
- const result = await deps.handleRideShotgunStart({
441
- durationSeconds,
442
- intervalSeconds,
443
- mode,
444
- targetDomain,
445
- navigateDomain,
446
- autoNavigate,
447
- });
448
-
449
- log.info(
450
- {
451
- watchId: result.watchId,
452
- sessionId: result.sessionId,
453
- durationSeconds,
454
- mode,
455
- },
456
- "Ride shotgun started via HTTP",
457
- );
458
-
459
- return Response.json(result, { status: 201 });
460
- } catch (err) {
461
- const message = err instanceof Error ? err.message : String(err);
462
- log.error({ err }, "Failed to start ride shotgun via HTTP");
463
- return httpError("INTERNAL_ERROR", message, 500);
464
- }
465
- }
466
-
467
- /**
468
- * POST /v1/computer-use/ride-shotgun/stop — stop a ride-shotgun session.
469
- *
470
- * Body: { watchId }
471
- */
472
- async function handleRideShotgunStopRoute(
473
- req: Request,
474
- deps: ComputerUseDeps,
475
- ): Promise<Response> {
476
- const body = (await req.json()) as { watchId?: string };
477
-
478
- if (!body.watchId || typeof body.watchId !== "string") {
479
- return httpError("BAD_REQUEST", "watchId is required", 400);
480
- }
481
-
482
- try {
483
- await deps.handleRideShotgunStop(body.watchId);
484
-
485
- log.info({ watchId: body.watchId }, "Ride shotgun stopped via HTTP");
486
- return Response.json({ ok: true });
487
- } catch (err) {
488
- const message = err instanceof Error ? err.message : String(err);
489
- log.error(
490
- { err, watchId: body.watchId },
491
- "Failed to stop ride shotgun via HTTP",
492
- );
493
- return httpError("INTERNAL_ERROR", message, 500);
494
- }
495
- }
496
-
497
- /**
498
- * GET /v1/computer-use/ride-shotgun/status/:watchId — get ride-shotgun session status.
499
- */
500
- function handleRideShotgunStatusRoute(
501
- watchId: string,
502
- deps: ComputerUseDeps,
503
- ): Response {
504
- const status = deps.getRideShotgunStatus(watchId);
505
- if (!status) {
506
- return httpError("NOT_FOUND", "Session not found", 404);
507
- }
508
- return Response.json(status);
509
- }
510
-
511
- /**
512
- * POST /v1/computer-use/watch — send a watch observation.
513
- *
514
- * Body: { watchId, sessionId, ocrText, appName?, windowTitle?,
515
- * bundleIdentifier?, timestamp, captureIndex, totalExpected }
516
- */
517
- async function handleWatchObservationRoute(
518
- req: Request,
519
- deps: ComputerUseDeps,
520
- ): Promise<Response> {
521
- const body = (await req.json()) as {
522
- watchId?: string;
523
- sessionId?: string;
524
- ocrText?: string;
525
- appName?: string;
526
- windowTitle?: string;
527
- bundleIdentifier?: string;
528
- timestamp?: number;
529
- captureIndex?: number;
530
- totalExpected?: number;
531
- };
532
-
533
- if (!body.watchId || typeof body.watchId !== "string") {
534
- return httpError("BAD_REQUEST", "watchId is required", 400);
535
- }
536
- if (!body.sessionId || typeof body.sessionId !== "string") {
537
- return httpError("BAD_REQUEST", "sessionId is required", 400);
538
- }
539
- if (!body.ocrText || typeof body.ocrText !== "string") {
540
- return httpError("BAD_REQUEST", "ocrText is required", 400);
541
- }
542
- if (typeof body.timestamp !== "number") {
543
- return httpError("BAD_REQUEST", "timestamp is required", 400);
544
- }
545
- if (typeof body.captureIndex !== "number") {
546
- return httpError("BAD_REQUEST", "captureIndex is required", 400);
547
- }
548
- if (typeof body.totalExpected !== "number") {
549
- return httpError("BAD_REQUEST", "totalExpected is required", 400);
550
- }
551
-
552
- try {
553
- await deps.handleWatchObservation({
554
- watchId: body.watchId,
555
- sessionId: body.sessionId,
556
- ocrText: body.ocrText,
557
- appName: body.appName,
558
- windowTitle: body.windowTitle,
559
- bundleIdentifier: body.bundleIdentifier,
560
- timestamp: body.timestamp,
561
- captureIndex: body.captureIndex,
562
- totalExpected: body.totalExpected,
563
- });
564
-
565
- return Response.json({ ok: true });
566
- } catch (err) {
567
- const message = err instanceof Error ? err.message : String(err);
568
- log.error(
569
- { err, watchId: body.watchId },
570
- "Failed to handle watch observation via HTTP",
571
- );
572
- return httpError("INTERNAL_ERROR", message, 500);
573
- }
574
- }
575
-
576
- // ---------------------------------------------------------------------------
577
- // Route definitions
578
- // ---------------------------------------------------------------------------
579
-
580
- export function computerUseRouteDefinitions(deps: {
581
- getComputerUseDeps?: () => ComputerUseDeps;
582
- }): RouteDefinition[] {
583
- const getDeps = (): ComputerUseDeps => {
584
- if (!deps.getComputerUseDeps) {
585
- throw new Error("Computer use deps not available");
586
- }
587
- return deps.getComputerUseDeps();
588
- };
589
-
590
- return [
591
- {
592
- endpoint: "computer-use/sessions",
593
- method: "POST",
594
- policyKey: "computer-use/sessions",
595
- handler: async ({ req }) => handleCreateSession(req, getDeps()),
596
- },
597
- {
598
- endpoint: "computer-use/sessions/:id/abort",
599
- method: "POST",
600
- policyKey: "computer-use/sessions/abort",
601
- handler: ({ params }) => handleAbortSession(params.id, getDeps()),
602
- },
603
- {
604
- endpoint: "computer-use/observations",
605
- method: "POST",
606
- policyKey: "computer-use/observations",
607
- handler: async ({ req }) => handleObservation(req, getDeps()),
608
- },
609
- {
610
- endpoint: "computer-use/tasks",
611
- method: "POST",
612
- policyKey: "computer-use/tasks",
613
- handler: async ({ req }) => handleTaskSubmit(req, getDeps()),
614
- },
615
- {
616
- endpoint: "computer-use/ride-shotgun/start",
617
- method: "POST",
618
- policyKey: "computer-use/ride-shotgun/start",
619
- handler: async ({ req }) => handleRideShotgunStartRoute(req, getDeps()),
620
- },
621
- {
622
- endpoint: "computer-use/ride-shotgun/stop",
623
- method: "POST",
624
- policyKey: "computer-use/ride-shotgun/stop",
625
- handler: async ({ req }) => handleRideShotgunStopRoute(req, getDeps()),
626
- },
627
- {
628
- endpoint: "computer-use/ride-shotgun/status/:watchId",
629
- method: "GET",
630
- policyKey: "computer-use/ride-shotgun/status",
631
- handler: ({ params }) =>
632
- handleRideShotgunStatusRoute(params.watchId, getDeps()),
633
- },
634
- {
635
- endpoint: "computer-use/watch",
636
- method: "POST",
637
- policyKey: "computer-use/watch",
638
- handler: async ({ req }) => handleWatchObservationRoute(req, getDeps()),
639
- },
640
- ];
641
- }