@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,10 +1,16 @@
1
1
  /**
2
2
  * Low-level Slack Web API wrapper.
3
3
  *
4
- * All methods take a user OAuth token and throw SlackApiError on failures.
5
- * Throws with status: 401 on auth errors for withValidToken compatibility.
4
+ * All methods accept either an OAuthConnection or a raw token string.
5
+ * Throws SlackApiError on failures, with status: 401 on auth errors
6
+ * for withValidToken compatibility.
7
+ *
8
+ * String overloads are retained for non-OAuth callers (e.g. slack/share.ts)
9
+ * that pass raw bot tokens via resolveSlackToken(). These bypass the
10
+ * OAuthConnection model by design.
6
11
  */
7
12
 
13
+ import type { OAuthConnection } from "../../../oauth/connection.js";
8
14
  import type {
9
15
  SlackApiResponse,
10
16
  SlackAuthTestResponse,
@@ -46,7 +52,159 @@ function sleepMs(ms: number): Promise<void> {
46
52
  return new Promise((resolve) => setTimeout(resolve, ms));
47
53
  }
48
54
 
49
- async function request<T extends SlackApiResponse>(
55
+ /**
56
+ * Check a Slack API response envelope for errors and map to SlackApiError.
57
+ * Returns the data if ok, throws otherwise.
58
+ */
59
+ function checkSlackEnvelope<T extends SlackApiResponse>(data: T): T {
60
+ if (!data.ok) {
61
+ const slackError = data.error ?? "unknown_error";
62
+ const status = [
63
+ "invalid_auth",
64
+ "token_expired",
65
+ "token_revoked",
66
+ "not_authed",
67
+ ].includes(slackError)
68
+ ? 401
69
+ : 400;
70
+ throw new SlackApiError(
71
+ status,
72
+ slackError,
73
+ `Slack API error: ${slackError}`,
74
+ );
75
+ }
76
+ return data;
77
+ }
78
+
79
+ /**
80
+ * Build a Slack API request using a raw token (for retry via `connection.withToken`).
81
+ */
82
+ async function rawSlackRequest<T extends SlackApiResponse>(
83
+ token: string,
84
+ method: string,
85
+ query: Record<string, string> | undefined,
86
+ body: Record<string, unknown> | undefined,
87
+ ): Promise<T> {
88
+ let url = `${SLACK_API_BASE}/${method}`;
89
+ const headers: Record<string, string> = {
90
+ Authorization: `Bearer ${token}`,
91
+ };
92
+
93
+ let init: RequestInit;
94
+ if (body) {
95
+ headers["Content-Type"] = "application/json; charset=utf-8";
96
+ init = { method: "POST", headers, body: JSON.stringify(body) };
97
+ } else {
98
+ if (query && Object.keys(query).length > 0) {
99
+ url += `?${new URLSearchParams(query)}`;
100
+ }
101
+ init = { method: "GET", headers };
102
+ }
103
+
104
+ const resp = await fetch(url, init);
105
+ if (resp.status === 429) {
106
+ throw new SlackApiError(429, "rate_limited", "Slack API rate limited");
107
+ }
108
+ if (!resp.ok) {
109
+ throw new SlackApiError(
110
+ resp.status,
111
+ `http_${resp.status}`,
112
+ `Slack API HTTP ${resp.status}`,
113
+ );
114
+ }
115
+ return checkSlackEnvelope((await resp.json()) as T);
116
+ }
117
+
118
+ /**
119
+ * Execute a Slack API request via OAuthConnection with rate-limit retry.
120
+ *
121
+ * Slack returns HTTP 200 with `{ ok: false, error: "invalid_auth" }` for
122
+ * auth errors. Because `connection.request()` delegates to `withValidToken`
123
+ * which only retries on HTTP-level 401s, we catch Slack envelope auth
124
+ * errors (mapped to SlackApiError with status 401) and perform a single
125
+ * retry via `connection.withToken()` which forces a token refresh before
126
+ * giving us the new token.
127
+ */
128
+ async function requestViaConnection<T extends SlackApiResponse>(
129
+ connection: OAuthConnection,
130
+ method: string,
131
+ params?: Record<string, string | undefined>,
132
+ body?: Record<string, unknown>,
133
+ ): Promise<T> {
134
+ const query: Record<string, string> | undefined = params
135
+ ? Object.fromEntries(
136
+ Object.entries(params).filter(
137
+ (entry): entry is [string, string] => entry[1] !== undefined,
138
+ ),
139
+ )
140
+ : undefined;
141
+
142
+ for (let attempt = 0; attempt <= MAX_RATE_LIMIT_RETRIES; attempt++) {
143
+ const resp = await connection.request({
144
+ method: body ? "POST" : "GET",
145
+ path: `/${method}`,
146
+ query: query && Object.keys(query).length > 0 ? query : undefined,
147
+ body,
148
+ });
149
+
150
+ // Handle 429 rate limits with Retry-After backoff
151
+ if (resp.status === 429) {
152
+ if (attempt >= MAX_RATE_LIMIT_RETRIES) {
153
+ throw new SlackApiError(429, "rate_limited", "Slack API rate limited");
154
+ }
155
+ const retryAfter =
156
+ parseInt(
157
+ resp.headers["retry-after"] ?? resp.headers["Retry-After"] ?? "",
158
+ 10,
159
+ ) || DEFAULT_RETRY_AFTER_S;
160
+ await sleepMs(retryAfter * 1000);
161
+ continue;
162
+ }
163
+
164
+ if (resp.status >= 400) {
165
+ throw new SlackApiError(
166
+ resp.status,
167
+ `http_${resp.status}`,
168
+ `Slack API HTTP ${resp.status}`,
169
+ );
170
+ }
171
+
172
+ const data = resp.body as T;
173
+
174
+ // Handle rate_limited error in response body (some Slack APIs return 200 with error)
175
+ if (
176
+ !data.ok &&
177
+ data.error === "rate_limited" &&
178
+ attempt < MAX_RATE_LIMIT_RETRIES
179
+ ) {
180
+ await sleepMs(DEFAULT_RETRY_AFTER_S * 1000);
181
+ continue;
182
+ }
183
+
184
+ try {
185
+ return checkSlackEnvelope(data);
186
+ } catch (err) {
187
+ // Slack envelope auth errors (invalid_auth, token_expired, etc.) come
188
+ // back as HTTP 200, so they escape withValidToken's retry scope inside
189
+ // connection.request(). Catch them here and retry once with a freshly-
190
+ // refreshed token via connection.withToken().
191
+ if (err instanceof SlackApiError && err.status === 401) {
192
+ return connection.withToken((freshToken) =>
193
+ rawSlackRequest<T>(freshToken, method, query, body),
194
+ );
195
+ }
196
+ throw err;
197
+ }
198
+ }
199
+
200
+ // Unreachable, but TypeScript needs this
201
+ throw new SlackApiError(429, "rate_limited", "Slack API rate limited");
202
+ }
203
+
204
+ /**
205
+ * Execute a Slack API request via raw token with rate-limit retry.
206
+ */
207
+ async function requestViaToken<T extends SlackApiResponse>(
50
208
  token: string,
51
209
  method: string,
52
210
  params?: Record<string, string | undefined>,
@@ -96,68 +254,76 @@ async function request<T extends SlackApiResponse>(
96
254
  }
97
255
 
98
256
  const data = (await resp.json()) as T;
99
- if (!data.ok) {
100
- const slackError = data.error ?? "unknown_error";
101
257
 
102
- // Handle rate_limited error in response body (some Slack APIs return 200 with error)
103
- if (slackError === "rate_limited" && attempt < MAX_RATE_LIMIT_RETRIES) {
104
- await sleepMs(DEFAULT_RETRY_AFTER_S * 1000);
105
- continue;
106
- }
107
-
108
- // Map auth errors to 401 for token-manager retry
109
- const status = [
110
- "invalid_auth",
111
- "token_expired",
112
- "token_revoked",
113
- "not_authed",
114
- ].includes(slackError)
115
- ? 401
116
- : 400;
117
- throw new SlackApiError(
118
- status,
119
- slackError,
120
- `Slack API error: ${slackError}`,
121
- );
258
+ // Handle rate_limited error in response body (some Slack APIs return 200 with error)
259
+ if (
260
+ !data.ok &&
261
+ data.error === "rate_limited" &&
262
+ attempt < MAX_RATE_LIMIT_RETRIES
263
+ ) {
264
+ await sleepMs(DEFAULT_RETRY_AFTER_S * 1000);
265
+ continue;
122
266
  }
123
267
 
124
- return data;
268
+ return checkSlackEnvelope(data);
125
269
  }
126
270
 
127
271
  // Unreachable, but TypeScript needs this
128
272
  throw new SlackApiError(429, "rate_limited", "Slack API rate limited");
129
273
  }
130
274
 
131
- export async function authTest(token: string): Promise<SlackAuthTestResponse> {
132
- return request<SlackAuthTestResponse>(token, "auth.test");
275
+ async function request<T extends SlackApiResponse>(
276
+ connectionOrToken: OAuthConnection | string,
277
+ method: string,
278
+ params?: Record<string, string | undefined>,
279
+ body?: Record<string, unknown>,
280
+ ): Promise<T> {
281
+ if (typeof connectionOrToken === "string") {
282
+ return requestViaToken<T>(connectionOrToken, method, params, body);
283
+ }
284
+ return requestViaConnection<T>(connectionOrToken, method, params, body);
285
+ }
286
+
287
+ export async function authTest(
288
+ connectionOrToken: OAuthConnection | string,
289
+ ): Promise<SlackAuthTestResponse> {
290
+ return request<SlackAuthTestResponse>(connectionOrToken, "auth.test");
133
291
  }
134
292
 
135
293
  export async function listConversations(
136
- token: string,
294
+ connectionOrToken: OAuthConnection | string,
137
295
  types = "public_channel,private_channel,mpim,im",
138
296
  excludeArchived = true,
139
297
  limit = 200,
140
298
  cursor?: string,
141
299
  ): Promise<SlackConversationsListResponse> {
142
- return request<SlackConversationsListResponse>(token, "conversations.list", {
143
- types,
144
- exclude_archived: String(excludeArchived),
145
- limit: String(limit),
146
- cursor,
147
- });
300
+ return request<SlackConversationsListResponse>(
301
+ connectionOrToken,
302
+ "conversations.list",
303
+ {
304
+ types,
305
+ exclude_archived: String(excludeArchived),
306
+ limit: String(limit),
307
+ cursor,
308
+ },
309
+ );
148
310
  }
149
311
 
150
312
  export async function conversationInfo(
151
- token: string,
313
+ connectionOrToken: OAuthConnection | string,
152
314
  channel: string,
153
315
  ): Promise<SlackConversationInfoResponse> {
154
- return request<SlackConversationInfoResponse>(token, "conversations.info", {
155
- channel,
156
- });
316
+ return request<SlackConversationInfoResponse>(
317
+ connectionOrToken,
318
+ "conversations.info",
319
+ {
320
+ channel,
321
+ },
322
+ );
157
323
  }
158
324
 
159
325
  export async function conversationHistory(
160
- token: string,
326
+ connectionOrToken: OAuthConnection | string,
161
327
  channel: string,
162
328
  limit = 50,
163
329
  latest?: string,
@@ -165,7 +331,7 @@ export async function conversationHistory(
165
331
  cursor?: string,
166
332
  ): Promise<SlackConversationHistoryResponse> {
167
333
  return request<SlackConversationHistoryResponse>(
168
- token,
334
+ connectionOrToken,
169
335
  "conversations.history",
170
336
  {
171
337
  channel,
@@ -178,13 +344,13 @@ export async function conversationHistory(
178
344
  }
179
345
 
180
346
  export async function conversationReplies(
181
- token: string,
347
+ connectionOrToken: OAuthConnection | string,
182
348
  channel: string,
183
349
  ts: string,
184
350
  limit = 50,
185
351
  ): Promise<SlackConversationRepliesResponse> {
186
352
  return request<SlackConversationRepliesResponse>(
187
- token,
353
+ connectionOrToken,
188
354
  "conversations.replies",
189
355
  {
190
356
  channel,
@@ -195,12 +361,12 @@ export async function conversationReplies(
195
361
  }
196
362
 
197
363
  export async function conversationMark(
198
- token: string,
364
+ connectionOrToken: OAuthConnection | string,
199
365
  channel: string,
200
366
  ts: string,
201
367
  ): Promise<SlackConversationMarkResponse> {
202
368
  return request<SlackConversationMarkResponse>(
203
- token,
369
+ connectionOrToken,
204
370
  "conversations.mark",
205
371
  undefined,
206
372
  {
@@ -211,11 +377,11 @@ export async function conversationMark(
211
377
  }
212
378
 
213
379
  export async function conversationsOpen(
214
- token: string,
380
+ connectionOrToken: OAuthConnection | string,
215
381
  userId: string,
216
382
  ): Promise<SlackConversationsOpenResponse> {
217
383
  return request<SlackConversationsOpenResponse>(
218
- token,
384
+ connectionOrToken,
219
385
  "conversations.open",
220
386
  undefined,
221
387
  {
@@ -225,10 +391,12 @@ export async function conversationsOpen(
225
391
  }
226
392
 
227
393
  export async function userInfo(
228
- token: string,
394
+ connectionOrToken: OAuthConnection | string,
229
395
  userId: string,
230
396
  ): Promise<SlackUserInfoResponse> {
231
- return request<SlackUserInfoResponse>(token, "users.info", { user: userId });
397
+ return request<SlackUserInfoResponse>(connectionOrToken, "users.info", {
398
+ user: userId,
399
+ });
232
400
  }
233
401
 
234
402
  export interface PostMessageOptions {
@@ -237,7 +405,7 @@ export interface PostMessageOptions {
237
405
  }
238
406
 
239
407
  export async function postMessage(
240
- token: string,
408
+ connectionOrToken: OAuthConnection | string,
241
409
  channel: string,
242
410
  text: string,
243
411
  optionsOrThreadTs?: PostMessageOptions | string,
@@ -250,7 +418,7 @@ export async function postMessage(
250
418
  if (opts.threadTs) body.thread_ts = opts.threadTs;
251
419
  if (opts.blocks) body.blocks = opts.blocks;
252
420
  return request<SlackPostMessageResponse>(
253
- token,
421
+ connectionOrToken,
254
422
  "chat.postMessage",
255
423
  undefined,
256
424
  body,
@@ -264,7 +432,7 @@ export async function postMessage(
264
432
  * after posting, and they disappear when the user reloads the Slack client.
265
433
  */
266
434
  export async function postEphemeral(
267
- token: string,
435
+ connectionOrToken: OAuthConnection | string,
268
436
  channel: string,
269
437
  user: string,
270
438
  text: string,
@@ -273,7 +441,7 @@ export async function postEphemeral(
273
441
  const body: Record<string, unknown> = { channel, user, text };
274
442
  if (threadTs) body.thread_ts = threadTs;
275
443
  return request<SlackPostEphemeralResponse>(
276
- token,
444
+ connectionOrToken,
277
445
  "chat.postEphemeral",
278
446
  undefined,
279
447
  body,
@@ -281,61 +449,80 @@ export async function postEphemeral(
281
449
  }
282
450
 
283
451
  export async function searchMessages(
284
- token: string,
452
+ connectionOrToken: OAuthConnection | string,
285
453
  query: string,
286
454
  count = 20,
287
455
  page = 1,
288
456
  ): Promise<SlackSearchMessagesResponse> {
289
- return request<SlackSearchMessagesResponse>(token, "search.messages", {
290
- query,
291
- count: String(count),
292
- page: String(page),
293
- });
457
+ return request<SlackSearchMessagesResponse>(
458
+ connectionOrToken,
459
+ "search.messages",
460
+ {
461
+ query,
462
+ count: String(count),
463
+ page: String(page),
464
+ },
465
+ );
294
466
  }
295
467
 
296
468
  export async function addReaction(
297
- token: string,
469
+ connectionOrToken: OAuthConnection | string,
298
470
  channel: string,
299
471
  timestamp: string,
300
472
  name: string,
301
473
  ): Promise<SlackReactionAddResponse> {
302
- return request<SlackReactionAddResponse>(token, "reactions.add", undefined, {
303
- channel,
304
- timestamp,
305
- name,
306
- });
474
+ return request<SlackReactionAddResponse>(
475
+ connectionOrToken,
476
+ "reactions.add",
477
+ undefined,
478
+ {
479
+ channel,
480
+ timestamp,
481
+ name,
482
+ },
483
+ );
307
484
  }
308
485
 
309
486
  export async function updateMessage(
310
- token: string,
487
+ connectionOrToken: OAuthConnection | string,
311
488
  channel: string,
312
489
  ts: string,
313
490
  text: string,
314
491
  ): Promise<SlackChatUpdateResponse> {
315
- return request<SlackChatUpdateResponse>(token, "chat.update", undefined, {
316
- channel,
317
- ts,
318
- text,
319
- });
492
+ return request<SlackChatUpdateResponse>(
493
+ connectionOrToken,
494
+ "chat.update",
495
+ undefined,
496
+ {
497
+ channel,
498
+ ts,
499
+ text,
500
+ },
501
+ );
320
502
  }
321
503
 
322
504
  export async function deleteMessage(
323
- token: string,
505
+ connectionOrToken: OAuthConnection | string,
324
506
  channel: string,
325
507
  ts: string,
326
508
  ): Promise<SlackChatDeleteResponse> {
327
- return request<SlackChatDeleteResponse>(token, "chat.delete", undefined, {
328
- channel,
329
- ts,
330
- });
509
+ return request<SlackChatDeleteResponse>(
510
+ connectionOrToken,
511
+ "chat.delete",
512
+ undefined,
513
+ {
514
+ channel,
515
+ ts,
516
+ },
517
+ );
331
518
  }
332
519
 
333
520
  export async function leaveConversation(
334
- token: string,
521
+ connectionOrToken: OAuthConnection | string,
335
522
  channel: string,
336
523
  ): Promise<SlackConversationLeaveResponse> {
337
524
  return request<SlackConversationLeaveResponse>(
338
- token,
525
+ connectionOrToken,
339
526
  "conversations.leave",
340
527
  undefined,
341
528
  {
@@ -6,15 +6,18 @@
6
6
  * with OAuth tokens, Telegram delivery is proxied through the gateway which
7
7
  * owns the bot token and handles Telegram API retries.
8
8
  *
9
- * The `token` parameter in MessagingProvider methods is unused for Telegram
10
- * because delivery is authenticated via the gateway's bearer token, not
11
- * a per-user OAuth token.
9
+ * The `connectionOrToken` parameter in MessagingProvider methods is unused
10
+ * for Telegram because delivery is authenticated via the gateway's bearer
11
+ * token, not a per-user OAuth token.
12
12
  */
13
13
 
14
14
  import { getGatewayInternalBaseUrl } from "../../../config/env.js";
15
15
  import { getOrCreateConversation } from "../../../memory/conversation-key-store.js";
16
16
  import * as externalConversationStore from "../../../memory/external-conversation-store.js";
17
+ import type { OAuthConnection } from "../../../oauth/connection.js";
18
+ import { getConnectionByProvider } from "../../../oauth/oauth-store.js";
17
19
  import { mintDaemonDeliveryToken } from "../../../runtime/auth/token-service.js";
20
+ import { credentialKey } from "../../../security/credential-key.js";
18
21
  import { getSecureKey } from "../../../security/secure-keys.js";
19
22
  import type { MessagingProvider } from "../../provider.js";
20
23
  import type {
@@ -30,7 +33,7 @@ import type {
30
33
  } from "../../provider-types.js";
31
34
  import * as telegram from "./client.js";
32
35
 
33
- /** Resolve the gateway base URL, preferring GATEWAY_INTERNAL_BASE_URL if set. */
36
+ /** Resolve the gateway base URL. */
34
37
  function getGatewayUrl(): string {
35
38
  return getGatewayInternalBaseUrl();
36
39
  }
@@ -42,7 +45,7 @@ function getBearerToken(): string {
42
45
 
43
46
  /** Read the Telegram bot token from the credential vault. */
44
47
  function getBotToken(): string | undefined {
45
- return getSecureKey("credential:telegram:bot_token");
48
+ return getSecureKey(credentialKey("telegram", "bot_token"));
46
49
  }
47
50
 
48
51
  export const telegramBotMessagingProvider: MessagingProvider = {
@@ -52,23 +55,21 @@ export const telegramBotMessagingProvider: MessagingProvider = {
52
55
  capabilities: new Set(["send"]),
53
56
 
54
57
  /**
55
- * Custom connectivity check. The standard registry check looks for
56
- * credential:telegram:access_token, but the Telegram bot token is
57
- * stored as credential:telegram:bot_token. This method lets the
58
- * registry detect that Telegram credentials exist.
58
+ * Custom connectivity check using the oauth_connection record as the
59
+ * single source of truth, consistent with integration-status.ts.
59
60
  *
60
61
  * Both bot_token and webhook_secret are required — the gateway's
61
62
  * /deliver/telegram endpoint rejects requests without the webhook
62
63
  * secret, so partial credentials would cause every send to fail.
63
64
  */
64
65
  isConnected(): boolean {
65
- return (
66
- getBotToken() !== undefined &&
67
- !!getSecureKey("credential:telegram:webhook_secret")
68
- );
66
+ const conn = getConnectionByProvider("telegram");
67
+ return !!(conn && conn.status === "active");
69
68
  },
70
69
 
71
- async testConnection(_token: string): Promise<ConnectionInfo> {
70
+ async testConnection(
71
+ _connectionOrToken: OAuthConnection | string,
72
+ ): Promise<ConnectionInfo> {
72
73
  const botToken = getBotToken();
73
74
  if (!botToken) {
74
75
  return {
@@ -113,7 +114,7 @@ export const telegramBotMessagingProvider: MessagingProvider = {
113
114
  },
114
115
 
115
116
  async sendMessage(
116
- _token: string,
117
+ _connectionOrToken: OAuthConnection | string,
117
118
  conversationId: string,
118
119
  text: string,
119
120
  _options?: SendOptions,
@@ -151,7 +152,7 @@ export const telegramBotMessagingProvider: MessagingProvider = {
151
152
  // interact with chats where users have initiated contact or the bot
152
153
  // has been added to a group.
153
154
  async listConversations(
154
- _token: string,
155
+ _connectionOrToken: OAuthConnection | string,
155
156
  _options?: ListOptions,
156
157
  ): Promise<Conversation[]> {
157
158
  return [];
@@ -159,7 +160,7 @@ export const telegramBotMessagingProvider: MessagingProvider = {
159
160
 
160
161
  // Telegram Bot API does not provide message history retrieval.
161
162
  async getHistory(
162
- _token: string,
163
+ _connectionOrToken: OAuthConnection | string,
163
164
  _conversationId: string,
164
165
  _options?: HistoryOptions,
165
166
  ): Promise<Message[]> {
@@ -168,7 +169,7 @@ export const telegramBotMessagingProvider: MessagingProvider = {
168
169
 
169
170
  // Telegram Bot API does not support message search.
170
171
  async search(
171
- _token: string,
172
+ _connectionOrToken: OAuthConnection | string,
172
173
  _query: string,
173
174
  _options?: SearchOptions,
174
175
  ): Promise<SearchResult> {
@@ -5,15 +5,17 @@
5
5
  * endpoint. Delivery is proxied through the gateway which owns the Meta Cloud API
6
6
  * credentials (phone_number_id + access_token).
7
7
  *
8
- * The `token` parameter in MessagingProvider methods is unused for WhatsApp
9
- * because delivery is authenticated via the gateway's bearer token, not
10
- * a per-user OAuth token.
8
+ * The `connectionOrToken` parameter in MessagingProvider methods is unused
9
+ * for WhatsApp because delivery is authenticated via the gateway's bearer
10
+ * token, not a per-user OAuth token.
11
11
  */
12
12
 
13
13
  import { getGatewayInternalBaseUrl } from "../../../config/env.js";
14
14
  import { getOrCreateConversation } from "../../../memory/conversation-key-store.js";
15
15
  import * as externalConversationStore from "../../../memory/external-conversation-store.js";
16
+ import type { OAuthConnection } from "../../../oauth/connection.js";
16
17
  import { mintDaemonDeliveryToken } from "../../../runtime/auth/token-service.js";
18
+ import { credentialKey } from "../../../security/credential-key.js";
17
19
  import { getSecureKey } from "../../../security/secure-keys.js";
18
20
  import type { MessagingProvider } from "../../provider.js";
19
21
  import type {
@@ -42,8 +44,8 @@ function getBearerToken(): string {
42
44
  /** Check whether WhatsApp credentials are stored. */
43
45
  function hasWhatsAppCredentials(): boolean {
44
46
  return (
45
- !!getSecureKey("credential:whatsapp:phone_number_id") &&
46
- !!getSecureKey("credential:whatsapp:access_token")
47
+ !!getSecureKey(credentialKey("whatsapp", "phone_number_id")) &&
48
+ !!getSecureKey(credentialKey("whatsapp", "access_token"))
47
49
  );
48
50
  }
49
51
 
@@ -60,7 +62,9 @@ export const whatsappMessagingProvider: MessagingProvider = {
60
62
  return hasWhatsAppCredentials();
61
63
  },
62
64
 
63
- async testConnection(_token: string): Promise<ConnectionInfo> {
65
+ async testConnection(
66
+ _connectionOrToken: OAuthConnection | string,
67
+ ): Promise<ConnectionInfo> {
64
68
  if (!hasWhatsAppCredentials()) {
65
69
  return {
66
70
  connected: false,
@@ -73,7 +77,9 @@ export const whatsappMessagingProvider: MessagingProvider = {
73
77
  };
74
78
  }
75
79
 
76
- const phoneNumberId = getSecureKey("credential:whatsapp:phone_number_id")!;
80
+ const phoneNumberId = getSecureKey(
81
+ credentialKey("whatsapp", "phone_number_id"),
82
+ )!;
77
83
 
78
84
  return {
79
85
  connected: true,
@@ -86,7 +92,7 @@ export const whatsappMessagingProvider: MessagingProvider = {
86
92
  },
87
93
 
88
94
  async sendMessage(
89
- _token: string,
95
+ _connectionOrToken: OAuthConnection | string,
90
96
  conversationId: string,
91
97
  text: string,
92
98
  options?: SendOptions,
@@ -130,7 +136,7 @@ export const whatsappMessagingProvider: MessagingProvider = {
130
136
 
131
137
  // WhatsApp does not support listing conversations via this provider.
132
138
  async listConversations(
133
- _token: string,
139
+ _connectionOrToken: OAuthConnection | string,
134
140
  _options?: ListOptions,
135
141
  ): Promise<Conversation[]> {
136
142
  return [];
@@ -138,7 +144,7 @@ export const whatsappMessagingProvider: MessagingProvider = {
138
144
 
139
145
  // WhatsApp does not provide message history retrieval via the gateway.
140
146
  async getHistory(
141
- _token: string,
147
+ _connectionOrToken: OAuthConnection | string,
142
148
  _conversationId: string,
143
149
  _options?: HistoryOptions,
144
150
  ): Promise<Message[]> {
@@ -147,7 +153,7 @@ export const whatsappMessagingProvider: MessagingProvider = {
147
153
 
148
154
  // WhatsApp does not support message search.
149
155
  async search(
150
- _token: string,
156
+ _connectionOrToken: OAuthConnection | string,
151
157
  _query: string,
152
158
  _options?: SearchOptions,
153
159
  ): Promise<SearchResult> {