@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.
- package/ARCHITECTURE.md +7 -7
- package/README.md +2 -23
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/architecture/security.md +5 -5
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/anthropic-provider.test.ts +156 -0
- package/src/__tests__/approval-cascade.test.ts +810 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-fill-credential.test.ts +5 -2
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +35 -25
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +9 -29
- package/src/__tests__/cli.test.ts +23 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
- package/src/__tests__/credential-broker-server-use.test.ts +22 -21
- package/src/__tests__/credential-broker.test.ts +2 -1
- package/src/__tests__/credential-metadata-store.test.ts +239 -26
- package/src/__tests__/credential-resolve.test.ts +5 -4
- package/src/__tests__/credential-security-e2e.test.ts +8 -8
- package/src/__tests__/credential-security-invariants.test.ts +111 -7
- package/src/__tests__/credential-vault-unit.test.ts +287 -54
- package/src/__tests__/credential-vault.test.ts +406 -12
- package/src/__tests__/credentials-cli.test.ts +82 -6
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-image-service.test.ts +75 -45
- package/src/__tests__/gemini-provider.test.ts +9 -6
- package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
- package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
- package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-grant-minting.test.ts +35 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-cu-proxy.test.ts +629 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +38 -25
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +11 -43
- package/src/__tests__/managed-proxy-context.test.ts +5 -3
- package/src/__tests__/media-generate-image.test.ts +63 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
- package/src/__tests__/messaging-send-tool.test.ts +4 -6
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +373 -14
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +756 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/schema-transforms.test.ts +226 -0
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
- package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/secret-onetime-send.test.ts +5 -3
- package/src/__tests__/send-endpoint-busy.test.ts +21 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-uninstall.test.ts +3 -3
- package/src/__tests__/skills.test.ts +3 -12
- package/src/__tests__/slack-channel-config.test.ts +76 -11
- package/src/__tests__/slack-share-routes.test.ts +17 -14
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +1 -22
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +2 -1
- package/src/__tests__/twilio-provider.test.ts +4 -2
- package/src/__tests__/twilio-routes.test.ts +5 -20
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +235 -0
- package/src/agent/loop.ts +76 -130
- package/src/calls/call-domain.ts +8 -10
- package/src/calls/relay-server.ts +9 -13
- package/src/calls/twilio-config.ts +4 -8
- package/src/calls/twilio-provider.ts +2 -1
- package/src/calls/twilio-rest.ts +2 -1
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +46 -15
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +110 -23
- package/src/cli/commands/oauth/apps.ts +255 -0
- package/src/cli/commands/oauth/connections.ts +299 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +242 -0
- package/src/cli/commands/skills.ts +4 -338
- package/src/cli/program.ts +1 -5
- package/src/cli/reference.ts +1 -3
- package/src/cli.ts +3 -2
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
- package/src/config/bundled-skills/gmail/SKILL.md +4 -4
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
- package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
- package/src/config/bundled-skills/messaging/SKILL.md +6 -6
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
- package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/schema.ts +3 -1
- package/src/config/skills.ts +21 -2
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +49 -10
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/guardian-action-generators.ts +4 -5
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +76 -56
- package/src/daemon/handlers/config-telegram.ts +53 -24
- package/src/daemon/handlers/sessions.ts +10 -24
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/host-cu-proxy.ts +401 -0
- package/src/daemon/lifecycle.ts +39 -63
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +2 -119
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/integrations.ts +1 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/server.ts +14 -21
- package/src/daemon/session-agent-loop-handlers.ts +2 -0
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-messaging.ts +3 -1
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +40 -28
- package/src/daemon/session-tool-setup.ts +20 -11
- package/src/daemon/session.ts +139 -16
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/email/providers/index.ts +2 -1
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/instrument.ts +15 -1
- package/src/logfire.ts +16 -5
- package/src/media/app-icon-generator.ts +30 -4
- package/src/media/avatar-router.ts +26 -3
- package/src/media/gemini-image-service.ts +28 -2
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/guardian-action-store.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +60 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/guardian.ts +1 -1
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/oauth.ts +65 -0
- package/src/messaging/provider.ts +19 -13
- package/src/messaging/providers/gmail/adapter.ts +40 -23
- package/src/messaging/providers/gmail/client.ts +283 -122
- package/src/messaging/providers/gmail/people-client.ts +32 -24
- package/src/messaging/providers/slack/adapter.ts +29 -19
- package/src/messaging/providers/slack/client.ts +265 -78
- package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
- package/src/messaging/providers/whatsapp/adapter.ts +17 -11
- package/src/messaging/registry.ts +2 -31
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +537 -0
- package/src/oauth/byo-connection.ts +128 -0
- package/src/oauth/connect-orchestrator.ts +139 -56
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +58 -0
- package/src/oauth/connection.ts +38 -0
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +496 -0
- package/src/oauth/platform-connection.test.ts +192 -0
- package/src/oauth/platform-connection.ts +111 -0
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +161 -0
- package/src/oauth/token-persistence.ts +74 -78
- package/src/permissions/checker.ts +8 -4
- package/src/permissions/defaults.ts +0 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +13 -0
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +70 -45
- package/src/providers/anthropic/client.ts +133 -24
- package/src/providers/gemini/client.ts +15 -6
- package/src/providers/managed-proxy/constants.ts +2 -2
- package/src/providers/managed-proxy/context.ts +5 -1
- package/src/providers/ratelimit.ts +17 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +1 -27
- package/src/runtime/AGENTS.md +17 -0
- package/src/runtime/auth/route-policy.ts +0 -3
- package/src/runtime/channel-invite-transports/telegram.ts +2 -1
- package/src/runtime/channel-readiness-service.ts +168 -195
- package/src/runtime/channel-readiness-types.ts +4 -0
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/guardian-action-conversation-turn.ts +1 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-message-composer.ts +3 -23
- package/src/runtime/http-server.ts +17 -10
- package/src/runtime/http-types.ts +2 -3
- package/src/runtime/middleware/rate-limiter.ts +74 -20
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/channel-readiness-routes.ts +2 -0
- package/src/runtime/routes/conversation-routes.ts +73 -19
- package/src/runtime/routes/diagnostics-routes.ts +11 -9
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/guardian-approval-interception.ts +20 -5
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -6
- package/src/runtime/routes/integrations/twilio.ts +6 -5
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/secret-routes.ts +3 -2
- package/src/runtime/routes/settings-routes.ts +113 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/schedule/integration-status.ts +10 -8
- package/src/security/credential-key.ts +14 -0
- package/src/security/keychain-broker-client.ts +5 -6
- package/src/security/oauth2.ts +1 -1
- package/src/security/token-manager.ts +145 -43
- package/src/skills/catalog-install.ts +358 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/apps/definitions.ts +0 -5
- package/src/tools/assets/materialize.ts +0 -5
- package/src/tools/assets/search.ts +0 -5
- package/src/tools/browser/headless-browser.ts +1 -67
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/claude-code/claude-code.ts +0 -5
- package/src/tools/computer-use/definitions.ts +46 -11
- package/src/tools/computer-use/registry.ts +4 -5
- package/src/tools/credentials/broker.ts +5 -4
- package/src/tools/credentials/metadata-store.ts +22 -74
- package/src/tools/credentials/resolve.ts +2 -1
- package/src/tools/credentials/vault.ts +139 -151
- package/src/tools/filesystem/edit.ts +1 -6
- package/src/tools/filesystem/read.ts +0 -5
- package/src/tools/filesystem/write.ts +1 -6
- package/src/tools/host-filesystem/edit.ts +1 -6
- package/src/tools/host-filesystem/read.ts +1 -6
- package/src/tools/host-filesystem/write.ts +1 -6
- package/src/tools/mcp/mcp-tool-factory.ts +18 -1
- package/src/tools/memory/definitions.ts +0 -5
- package/src/tools/network/web-fetch.ts +0 -5
- package/src/tools/network/web-search.ts +0 -5
- package/src/tools/registry.ts +2 -7
- package/src/tools/schema-transforms.ts +99 -0
- package/src/tools/skills/load.ts +62 -8
- package/src/tools/swarm/delegate.ts +0 -5
- package/src/tools/system/avatar-generator.ts +0 -5
- package/src/tools/ui-surface/definitions.ts +0 -15
- package/src/tools/watch/screen-watch.ts +0 -5
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/version.ts +10 -0
- package/src/watcher/providers/github.ts +51 -52
- package/src/watcher/providers/gmail.ts +88 -80
- package/src/watcher/providers/google-calendar.ts +94 -86
- package/src/watcher/providers/linear.ts +87 -93
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
- package/src/daemon/computer-use-session.ts +0 -1020
- package/src/daemon/ride-shotgun-handler.ts +0 -567
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
- package/src/runtime/telegram-streaming-delivery.ts +0 -383
- 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
|
|
5
|
-
* Throws with status: 401 on auth errors
|
|
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
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
|
|
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>(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
313
|
+
connectionOrToken: OAuthConnection | string,
|
|
152
314
|
channel: string,
|
|
153
315
|
): Promise<SlackConversationInfoResponse> {
|
|
154
|
-
return request<SlackConversationInfoResponse>(
|
|
155
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
364
|
+
connectionOrToken: OAuthConnection | string,
|
|
199
365
|
channel: string,
|
|
200
366
|
ts: string,
|
|
201
367
|
): Promise<SlackConversationMarkResponse> {
|
|
202
368
|
return request<SlackConversationMarkResponse>(
|
|
203
|
-
|
|
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
|
-
|
|
380
|
+
connectionOrToken: OAuthConnection | string,
|
|
215
381
|
userId: string,
|
|
216
382
|
): Promise<SlackConversationsOpenResponse> {
|
|
217
383
|
return request<SlackConversationsOpenResponse>(
|
|
218
|
-
|
|
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
|
-
|
|
394
|
+
connectionOrToken: OAuthConnection | string,
|
|
229
395
|
userId: string,
|
|
230
396
|
): Promise<SlackUserInfoResponse> {
|
|
231
|
-
return request<SlackUserInfoResponse>(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
452
|
+
connectionOrToken: OAuthConnection | string,
|
|
285
453
|
query: string,
|
|
286
454
|
count = 20,
|
|
287
455
|
page = 1,
|
|
288
456
|
): Promise<SlackSearchMessagesResponse> {
|
|
289
|
-
return request<SlackSearchMessagesResponse>(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
-
|
|
469
|
+
connectionOrToken: OAuthConnection | string,
|
|
298
470
|
channel: string,
|
|
299
471
|
timestamp: string,
|
|
300
472
|
name: string,
|
|
301
473
|
): Promise<SlackReactionAddResponse> {
|
|
302
|
-
return request<SlackReactionAddResponse>(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
487
|
+
connectionOrToken: OAuthConnection | string,
|
|
311
488
|
channel: string,
|
|
312
489
|
ts: string,
|
|
313
490
|
text: string,
|
|
314
491
|
): Promise<SlackChatUpdateResponse> {
|
|
315
|
-
return request<SlackChatUpdateResponse>(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
505
|
+
connectionOrToken: OAuthConnection | string,
|
|
324
506
|
channel: string,
|
|
325
507
|
ts: string,
|
|
326
508
|
): Promise<SlackChatDeleteResponse> {
|
|
327
|
-
return request<SlackChatDeleteResponse>(
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
521
|
+
connectionOrToken: OAuthConnection | string,
|
|
335
522
|
channel: string,
|
|
336
523
|
): Promise<SlackConversationLeaveResponse> {
|
|
337
524
|
return request<SlackConversationLeaveResponse>(
|
|
338
|
-
|
|
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 `
|
|
10
|
-
* because delivery is authenticated via the gateway's bearer
|
|
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
|
|
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("
|
|
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
|
|
56
|
-
*
|
|
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
|
-
|
|
66
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 `
|
|
9
|
-
* because delivery is authenticated via the gateway's bearer
|
|
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("
|
|
46
|
-
!!getSecureKey("
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
156
|
+
_connectionOrToken: OAuthConnection | string,
|
|
151
157
|
_query: string,
|
|
152
158
|
_options?: SearchOptions,
|
|
153
159
|
): Promise<SearchResult> {
|