@vellumai/assistant 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +163 -54
- package/docs/architecture/integrations.md +62 -67
- package/docs/credential-execution-service.md +3 -3
- package/docs/skills.md +100 -0
- package/package.json +1 -1
- package/src/__tests__/agent-loop.test.ts +111 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +3 -4
- package/src/__tests__/app-builder-tool-scripts.test.ts +13 -151
- package/src/__tests__/app-dir-path-guard.test.ts +78 -0
- package/src/__tests__/app-executors.test.ts +1 -291
- package/src/__tests__/app-git-history.test.ts +4 -4
- package/src/__tests__/app-routes-csp.test.ts +1 -0
- package/src/__tests__/app-store-dir-names.test.ts +426 -0
- package/src/__tests__/attachments-store.test.ts +169 -21
- package/src/__tests__/attachments.test.ts +115 -1
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/canonical-guardian-store.test.ts +38 -0
- package/src/__tests__/channel-reply-delivery.test.ts +55 -0
- package/src/__tests__/checker.test.ts +54 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +2 -0
- package/src/__tests__/claude-code-tool-profiles.test.ts +2 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -1
- package/src/__tests__/config-schema-cmd.test.ts +68 -21
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +156 -5
- package/src/__tests__/conversation-agent-loop.test.ts +297 -2
- package/src/__tests__/conversation-attachments.test.ts +17 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +277 -0
- package/src/__tests__/conversation-disk-view.test.ts +810 -0
- package/src/__tests__/conversation-error.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +551 -0
- package/src/__tests__/conversation-fork-route.test.ts +386 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +130 -0
- package/src/__tests__/conversation-media-retry.test.ts +8 -2
- package/src/__tests__/conversation-memory-dirty-tail.test.ts +150 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +7 -0
- package/src/__tests__/conversation-queue.test.ts +36 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +439 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +17 -2
- package/src/__tests__/conversation-skill-tools.test.ts +4 -9
- package/src/__tests__/conversation-slash-commands.test.ts +149 -0
- package/src/__tests__/conversation-store.test.ts +24 -21
- package/src/__tests__/conversation-surfaces-state-update.test.ts +246 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -0
- package/src/__tests__/conversation-title-service.test.ts +137 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +25 -315
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/conversation-wipe.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +44 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +11 -0
- package/src/__tests__/credential-security-invariants.test.ts +3 -0
- package/src/__tests__/credential-vault-unit.test.ts +5 -10
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +241 -0
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +214 -0
- package/src/__tests__/db-memory-archive-migration.test.ts +372 -0
- package/src/__tests__/db-memory-brief-state-migration.test.ts +213 -0
- package/src/__tests__/db-memory-reducer-checkpoints.test.ts +273 -0
- package/src/__tests__/diagnostics-export.test.ts +70 -1
- package/src/__tests__/first-greeting.test.ts +80 -0
- package/src/__tests__/gateway-only-guard.test.ts +1 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -7
- package/src/__tests__/history-repair.test.ts +32 -10
- package/src/__tests__/http-conversation-lineage.test.ts +251 -0
- package/src/__tests__/image-source-path-reinject.test.ts +136 -0
- package/src/__tests__/inline-command-runner.test.ts +311 -0
- package/src/__tests__/inline-skill-authoring-guard.test.ts +220 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +435 -0
- package/src/__tests__/list-messages-attachments.test.ts +96 -0
- package/src/__tests__/llm-context-normalization.test.ts +1116 -0
- package/src/__tests__/llm-context-route-provider.test.ts +217 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +270 -0
- package/src/__tests__/media-generate-image.test.ts +47 -94
- package/src/__tests__/memory-brief-open-loops.test.ts +530 -0
- package/src/__tests__/memory-brief-time.test.ts +285 -0
- package/src/__tests__/memory-brief-wrapper.test.ts +311 -0
- package/src/__tests__/memory-chunk-archive.test.ts +400 -0
- package/src/__tests__/memory-chunk-dual-write.test.ts +453 -0
- package/src/__tests__/memory-episode-archive.test.ts +370 -0
- package/src/__tests__/memory-episode-dual-write.test.ts +626 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +3 -1
- package/src/__tests__/memory-observation-archive.test.ts +375 -0
- package/src/__tests__/memory-observation-dual-write.test.ts +318 -0
- package/src/__tests__/memory-recall-quality.test.ts +7 -7
- package/src/__tests__/memory-reducer-store.test.ts +728 -0
- package/src/__tests__/memory-reducer-types.test.ts +699 -0
- package/src/__tests__/memory-reducer.test.ts +698 -0
- package/src/__tests__/memory-regressions.test.ts +6 -4
- package/src/__tests__/memory-simplified-config.test.ts +281 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +4 -1
- package/src/__tests__/migration-export-http.test.ts +3 -1
- package/src/__tests__/migration-import-commit-http.test.ts +18 -4
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -3
- package/src/__tests__/mime-builder.test.ts +3 -2
- package/src/__tests__/non-member-access-request.test.ts +12 -1
- package/src/__tests__/notification-decision-identity.test.ts +52 -0
- package/src/__tests__/oauth-apps-routes.test.ts +103 -0
- package/src/__tests__/oauth-store.test.ts +115 -0
- package/src/__tests__/parse-identity-fields.test.ts +129 -0
- package/src/__tests__/provider-error-scenarios.test.ts +1 -3
- package/src/__tests__/provider-failover-actual-provider.test.ts +66 -0
- package/src/__tests__/recording-handler.test.ts +17 -0
- package/src/__tests__/registry.test.ts +3 -8
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/runtime-attachment-metadata.test.ts +7 -3
- package/src/__tests__/schema-transforms.test.ts +165 -5
- package/src/__tests__/server-history-render.test.ts +2 -2
- package/src/__tests__/skill-load-inline-command.test.ts +598 -0
- package/src/__tests__/skill-load-inline-includes.test.ts +644 -0
- package/src/__tests__/skills-inline-command-expansions.test.ts +301 -0
- package/src/__tests__/skills-transitive-hash.test.ts +333 -0
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -2
- package/src/__tests__/starter-task-flow.test.ts +1 -0
- package/src/__tests__/suggestion-routes.test.ts +443 -0
- package/src/__tests__/swarm-conversation-integration.test.ts +1 -0
- package/src/__tests__/swarm-recursion.test.ts +1 -0
- package/src/__tests__/swarm-tool.test.ts +1 -0
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -5
- package/src/__tests__/top-level-renderer.test.ts +22 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +243 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +320 -0
- package/src/__tests__/web-fetch.test.ts +6 -2
- package/src/__tests__/workspace-migration-006-services-config.test.ts +335 -0
- package/src/__tests__/workspace-migration-007-web-search-provider-rename.test.ts +312 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +278 -0
- package/src/__tests__/workspace-migration-010-app-dir-rename.test.ts +275 -0
- package/src/__tests__/workspace-migration-012-rename-conversation-disk-view-dirs.test.ts +77 -0
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +401 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +328 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +6 -10
- package/src/agent/attachments.ts +27 -1
- package/src/agent/loop.ts +29 -1
- package/src/avatar/traits-png-sync.ts +80 -25
- package/src/bundler/app-bundler.ts +4 -4
- package/src/calls/call-domain.ts +1 -0
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/cli/commands/auth.ts +92 -0
- package/src/cli/commands/avatar.ts +7 -6
- package/src/cli/commands/config.ts +2 -0
- package/src/cli/commands/oauth/providers.ts +29 -0
- package/src/cli/program.ts +12 -0
- package/src/cli.ts +15 -48
- package/src/config/bundled-skills/app-builder/SKILL.md +103 -28
- package/src/config/bundled-skills/app-builder/TOOLS.json +5 -199
- package/src/config/bundled-skills/app-builder/tools/{app-query.ts → app-refresh.ts} +2 -2
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +6 -9
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +4 -6
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -3
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +2 -3
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -2
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +45 -72
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +2 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -1
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -3
- package/src/config/bundled-skills/skill-management/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
- package/src/config/bundled-skills/slack/tools/shared.ts +19 -4
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +2 -3
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -1
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -6
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +19 -83
- package/src/config/bundled-tool-registry.ts +2 -14
- package/src/config/feature-flag-registry.json +24 -0
- package/src/config/loader.ts +65 -0
- package/src/config/raw-config-utils.ts +58 -0
- package/src/config/schema-utils.ts +28 -7
- package/src/config/schema.ts +20 -0
- package/src/config/schemas/elevenlabs.ts +18 -0
- package/src/config/schemas/memory-lifecycle.ts +4 -2
- package/src/config/schemas/memory-simplified.ts +101 -0
- package/src/config/schemas/memory-storage.ts +1 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +8 -6
- package/src/config/skills.ts +50 -4
- package/src/contacts/contact-store.ts +13 -6
- package/src/contacts/contacts-write.ts +0 -1
- package/src/context/window-manager.ts +13 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +54 -8
- package/src/daemon/conversation-agent-loop.ts +127 -20
- package/src/daemon/conversation-attachments.ts +18 -36
- package/src/daemon/conversation-error.ts +2 -1
- package/src/daemon/conversation-history.ts +18 -4
- package/src/daemon/conversation-lifecycle.ts +50 -16
- package/src/daemon/conversation-messaging.ts +70 -26
- package/src/daemon/conversation-process.ts +58 -34
- package/src/daemon/conversation-runtime-assembly.ts +22 -38
- package/src/daemon/conversation-slash.ts +121 -256
- package/src/daemon/conversation-surfaces.ts +170 -24
- package/src/daemon/conversation-tool-setup.ts +0 -6
- package/src/daemon/conversation-workspace.ts +21 -1
- package/src/daemon/conversation.ts +69 -30
- package/src/daemon/first-greeting.ts +35 -0
- package/src/daemon/handlers/config-embeddings.ts +156 -0
- package/src/daemon/handlers/config-model.ts +62 -26
- package/src/daemon/handlers/conversations.ts +0 -23
- package/src/daemon/handlers/identity.ts +12 -1
- package/src/daemon/handlers/recording.ts +26 -21
- package/src/daemon/host-cu-proxy.ts +2 -2
- package/src/daemon/lifecycle.ts +115 -65
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +18 -0
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/shared.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/upgrades.ts +23 -0
- package/src/daemon/server.ts +83 -12
- package/src/daemon/shutdown-handlers.ts +8 -5
- package/src/daemon/startup-error.ts +9 -0
- package/src/daemon/tool-side-effects.ts +11 -28
- package/src/events/tool-permission-telemetry-listener.ts +1 -3
- package/src/followups/followup-store.ts +47 -1
- package/src/instrument.ts +0 -4
- package/src/media/app-icon-generator.ts +2 -2
- package/src/memory/app-git-service.ts +28 -16
- package/src/memory/app-store.ts +230 -41
- package/src/memory/archive-store.ts +400 -0
- package/src/memory/attachments-store.ts +558 -130
- package/src/memory/brief-formatting.ts +33 -0
- package/src/memory/brief-open-loops.ts +266 -0
- package/src/memory/brief-time.ts +161 -0
- package/src/memory/brief.ts +75 -0
- package/src/memory/conversation-attention-store.ts +70 -0
- package/src/memory/conversation-crud.ts +591 -8
- package/src/memory/conversation-directories.ts +125 -0
- package/src/memory/conversation-disk-view.ts +390 -0
- package/src/memory/conversation-key-store.ts +17 -5
- package/src/memory/conversation-queries.ts +5 -1
- package/src/memory/conversation-title-service.ts +21 -49
- package/src/memory/db-init.ts +40 -0
- package/src/memory/embedding-backend.ts +42 -53
- package/src/memory/embedding-gemini.test.ts +4 -4
- package/src/memory/embedding-local.ts +1 -3
- package/src/memory/embedding-ollama.ts +1 -3
- package/src/memory/embedding-openai.ts +1 -3
- package/src/memory/indexer.ts +114 -21
- package/src/memory/items-extractor.ts +42 -13
- package/src/memory/job-handlers/conversation-starters.ts +6 -1
- package/src/memory/job-handlers/embedding.test.ts +2 -4
- package/src/memory/job-handlers/embedding.ts +83 -0
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +6 -0
- package/src/memory/jobs-worker.ts +12 -0
- package/src/memory/llm-request-log-store.ts +100 -1
- package/src/memory/migrations/102-alter-table-columns.ts +5 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +3 -3
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +66 -70
- package/src/memory/migrations/148-drop-reminders-table.ts +5 -9
- package/src/memory/migrations/160-drop-loopback-port-column.ts +1 -3
- package/src/memory/migrations/174-rename-thread-starters-table.ts +0 -7
- package/src/memory/migrations/178-oauth-providers-managed-service-config-key.ts +15 -0
- package/src/memory/migrations/179-llm-request-log-message-id.ts +16 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +66 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +46 -0
- package/src/memory/migrations/182-oauth-providers-display-metadata.ts +20 -0
- package/src/memory/migrations/183-add-conversation-fork-lineage.ts +22 -0
- package/src/memory/migrations/184-llm-request-log-provider.ts +12 -0
- package/src/memory/migrations/185-memory-brief-state.ts +52 -0
- package/src/memory/migrations/186-memory-archive.ts +109 -0
- package/src/memory/migrations/187-memory-reducer-checkpoints.ts +19 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +13 -0
- package/src/memory/qdrant-client.ts +23 -4
- package/src/memory/reducer-store.ts +271 -0
- package/src/memory/reducer-types.ts +99 -0
- package/src/memory/reducer.ts +453 -0
- package/src/memory/retriever.test.ts +601 -2
- package/src/memory/retriever.ts +85 -9
- package/src/memory/schema/conversations.ts +9 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/infrastructure.ts +13 -7
- package/src/memory/schema/memory-archive.ts +121 -0
- package/src/memory/schema/memory-brief.ts +55 -0
- package/src/memory/schema/oauth.ts +6 -0
- package/src/memory/search/semantic.ts +17 -4
- package/src/messaging/providers/gmail/mime-builder.ts +3 -1
- package/src/notifications/copy-composer.ts +26 -0
- package/src/notifications/decision-engine.ts +14 -1
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +36 -0
- package/src/oauth/byo-connection.test.ts +1 -45
- package/src/oauth/byo-connection.ts +2 -8
- package/src/oauth/connect-orchestrator.ts +15 -11
- package/src/oauth/connection-resolver.test.ts +191 -0
- package/src/oauth/connection-resolver.ts +66 -38
- package/src/oauth/connection.ts +0 -1
- package/src/oauth/oauth-store.ts +99 -47
- package/src/oauth/platform-connection.test.ts +0 -1
- package/src/oauth/platform-connection.ts +11 -3
- package/src/oauth/seed-providers.ts +78 -3
- package/src/oauth/token-persistence.ts +16 -10
- package/src/permissions/checker.ts +160 -14
- package/src/permissions/defaults.ts +14 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -0
- package/src/providers/anthropic/client.ts +8 -1
- package/src/providers/failover.ts +4 -1
- package/src/providers/gemini/client.ts +50 -0
- package/src/providers/model-catalog.ts +92 -0
- package/src/providers/model-intents.ts +29 -20
- package/src/providers/openai/client.ts +49 -0
- package/src/providers/types.ts +2 -0
- package/src/runtime/access-request-helper.ts +16 -7
- package/src/runtime/auth/credential-service.ts +3 -1
- package/src/runtime/auth/route-policy.ts +14 -1
- package/src/runtime/btw-sidechain.ts +101 -0
- package/src/runtime/channel-reply-delivery.ts +17 -1
- package/src/runtime/http-router.ts +3 -1
- package/src/runtime/http-server.ts +196 -141
- package/src/runtime/http-types.ts +1 -0
- package/src/runtime/migrations/vbundle-builder.ts +5 -1
- package/src/runtime/routes/access-request-decision.ts +41 -0
- package/src/runtime/routes/app-management-routes.ts +6 -3
- package/src/runtime/routes/app-routes.ts +7 -3
- package/src/runtime/routes/approval-routes.ts +1 -0
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +34 -2
- package/src/runtime/routes/attachment-routes.ts +45 -15
- package/src/runtime/routes/btw-routes.ts +21 -61
- package/src/runtime/routes/conversation-management-routes.ts +74 -0
- package/src/runtime/routes/conversation-query-routes.ts +187 -10
- package/src/runtime/routes/conversation-routes.ts +269 -28
- package/src/runtime/routes/conversation-starter-routes.ts +9 -11
- package/src/runtime/routes/diagnostics-routes.ts +1 -0
- package/src/runtime/routes/identity-routes.ts +2 -35
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -2
- package/src/runtime/routes/llm-context-normalization.ts +1212 -0
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/memory-item-routes.test.ts +34 -0
- package/src/runtime/routes/memory-item-routes.ts +94 -5
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/oauth-apps.ts +291 -0
- package/src/runtime/routes/secret-routes.ts +30 -1
- package/src/runtime/routes/settings-routes.ts +14 -0
- package/src/runtime/routes/surface-action-routes.ts +68 -1
- package/src/runtime/routes/trace-event-routes.ts +4 -1
- package/src/schedule/schedule-store.ts +30 -21
- package/src/security/secure-keys.ts +21 -0
- package/src/signals/bash.ts +1 -1
- package/src/skills/inline-command-expansions.ts +204 -0
- package/src/skills/inline-command-render.ts +127 -0
- package/src/skills/inline-command-runner.ts +242 -0
- package/src/skills/transitive-version-hash.ts +88 -0
- package/src/swarm/backend-claude-code.ts +3 -6
- package/src/tasks/task-store.ts +43 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +3 -1
- package/src/tools/AGENTS.md +6 -10
- package/src/tools/apps/executors.ts +17 -232
- package/src/tools/claude-code/claude-code.ts +2 -3
- package/src/tools/credentials/vault.ts +7 -12
- package/src/tools/host-filesystem/read.ts +13 -10
- package/src/tools/network/__tests__/web-search.test.ts +4 -2
- package/src/tools/permission-checker.ts +8 -1
- package/src/tools/schedule/list.ts +2 -7
- package/src/tools/schema-transforms.ts +5 -0
- package/src/tools/shared/filesystem/format-diff.ts +2 -7
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/load.ts +140 -6
- package/src/tools/tool-manifest.ts +0 -6
- package/src/tools/ui-surface/definitions.ts +2 -2
- package/src/util/device-id.ts +28 -5
- package/src/util/platform.ts +24 -0
- package/src/util/pricing.ts +1 -0
- package/src/util/retry.ts +1 -3
- package/src/workspace/migrations/003-seed-device-id.ts +3 -4
- package/src/workspace/migrations/006-services-config.ts +5 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +12 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +10 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +223 -0
- package/src/workspace/migrations/{002-backfill-installation-id.ts → 011-backfill-installation-id.ts} +24 -13
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +64 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +11 -0
- package/src/workspace/migrations/rebuild-conversation-disk-view.ts +186 -0
- package/src/workspace/migrations/registry.ts +11 -1
- package/src/workspace/top-level-renderer.ts +12 -0
- package/src/__tests__/asset-materialize-tool.test.ts +0 -523
- package/src/__tests__/asset-search-tool.test.ts +0 -536
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +0 -56
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -762
- package/src/__tests__/media-visibility-policy.test.ts +0 -190
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +0 -21
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +0 -14
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -13
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +0 -23
- package/src/daemon/media-visibility-policy.ts +0 -59
- package/src/tools/assets/materialize.ts +0 -248
- package/src/tools/assets/search.ts +0 -400
|
@@ -25,31 +25,25 @@ export interface BYOOAuthConnectionOptions {
|
|
|
25
25
|
providerKey: string;
|
|
26
26
|
baseUrl: string;
|
|
27
27
|
accountInfo: string | null;
|
|
28
|
-
grantedScopes: string[];
|
|
29
|
-
credentialService: string;
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
export class BYOOAuthConnection implements OAuthConnection {
|
|
33
31
|
readonly id: string;
|
|
34
32
|
readonly providerKey: string;
|
|
35
33
|
readonly accountInfo: string | null;
|
|
36
|
-
readonly grantedScopes: string[];
|
|
37
34
|
|
|
38
35
|
private readonly baseUrl: string;
|
|
39
|
-
private readonly credentialService: string;
|
|
40
36
|
|
|
41
37
|
constructor(opts: BYOOAuthConnectionOptions) {
|
|
42
38
|
this.id = opts.id;
|
|
43
39
|
this.providerKey = opts.providerKey;
|
|
44
40
|
this.baseUrl = opts.baseUrl;
|
|
45
41
|
this.accountInfo = opts.accountInfo;
|
|
46
|
-
this.grantedScopes = opts.grantedScopes;
|
|
47
|
-
this.credentialService = opts.credentialService;
|
|
48
42
|
}
|
|
49
43
|
|
|
50
44
|
async request(req: OAuthConnectionRequest): Promise<OAuthConnectionResponse> {
|
|
51
45
|
return withValidToken(
|
|
52
|
-
this.
|
|
46
|
+
this.providerKey,
|
|
53
47
|
async (token) => {
|
|
54
48
|
const effectiveBaseUrl = req.baseUrl ?? this.baseUrl;
|
|
55
49
|
let fullUrl = `${effectiveBaseUrl}${req.path}`;
|
|
@@ -106,7 +100,7 @@ export class BYOOAuthConnection implements OAuthConnection {
|
|
|
106
100
|
}
|
|
107
101
|
|
|
108
102
|
async withToken<T>(fn: (token: string) => Promise<T>): Promise<T> {
|
|
109
|
-
return withValidToken(this.
|
|
103
|
+
return withValidToken(this.providerKey, fn, {
|
|
110
104
|
connectionId: this.id,
|
|
111
105
|
});
|
|
112
106
|
}
|
|
@@ -252,12 +252,13 @@ export async function orchestrateOAuthConnect(
|
|
|
252
252
|
prepared.completion
|
|
253
253
|
.then(async (result) => {
|
|
254
254
|
try {
|
|
255
|
-
let
|
|
255
|
+
let parsedAccountIdentifier: string | undefined;
|
|
256
256
|
|
|
257
|
-
//
|
|
257
|
+
// Parse account identifier from the provider's identity endpoint.
|
|
258
|
+
// Best-effort — format varies by provider and may fail.
|
|
258
259
|
if (behavior.identityVerifier) {
|
|
259
260
|
try {
|
|
260
|
-
|
|
261
|
+
parsedAccountIdentifier = await behavior.identityVerifier(
|
|
261
262
|
result.tokens.accessToken,
|
|
262
263
|
);
|
|
263
264
|
} catch {
|
|
@@ -270,19 +271,19 @@ export async function orchestrateOAuthConnect(
|
|
|
270
271
|
tokens: result.tokens,
|
|
271
272
|
grantedScopes: result.grantedScopes,
|
|
272
273
|
rawTokenResponse: result.rawTokenResponse,
|
|
273
|
-
|
|
274
|
+
parsedAccountIdentifier,
|
|
274
275
|
});
|
|
275
276
|
log.info(
|
|
276
277
|
{
|
|
277
278
|
service: resolvedService,
|
|
278
|
-
accountInfo: stored.accountInfo ??
|
|
279
|
+
accountInfo: stored.accountInfo ?? parsedAccountIdentifier,
|
|
279
280
|
},
|
|
280
281
|
"Deferred OAuth2 flow completed — tokens stored",
|
|
281
282
|
);
|
|
282
283
|
options.onDeferredComplete?.({
|
|
283
284
|
success: true,
|
|
284
285
|
service: resolvedService,
|
|
285
|
-
accountInfo: stored.accountInfo ??
|
|
286
|
+
accountInfo: stored.accountInfo ?? parsedAccountIdentifier,
|
|
286
287
|
});
|
|
287
288
|
} catch (err) {
|
|
288
289
|
log.error(
|
|
@@ -353,11 +354,14 @@ export async function orchestrateOAuthConnect(
|
|
|
353
354
|
: undefined,
|
|
354
355
|
);
|
|
355
356
|
|
|
356
|
-
//
|
|
357
|
-
|
|
357
|
+
// Parse account identifier from the provider's identity endpoint.
|
|
358
|
+
// Best-effort — format varies by provider and may fail.
|
|
359
|
+
let parsedAccountIdentifier: string | undefined;
|
|
358
360
|
if (behavior.identityVerifier) {
|
|
359
361
|
try {
|
|
360
|
-
|
|
362
|
+
parsedAccountIdentifier = await behavior.identityVerifier(
|
|
363
|
+
tokens.accessToken,
|
|
364
|
+
);
|
|
361
365
|
} catch {
|
|
362
366
|
// Non-fatal
|
|
363
367
|
}
|
|
@@ -368,14 +372,14 @@ export async function orchestrateOAuthConnect(
|
|
|
368
372
|
tokens,
|
|
369
373
|
grantedScopes,
|
|
370
374
|
rawTokenResponse,
|
|
371
|
-
|
|
375
|
+
parsedAccountIdentifier,
|
|
372
376
|
});
|
|
373
377
|
|
|
374
378
|
return {
|
|
375
379
|
success: true,
|
|
376
380
|
deferred: false,
|
|
377
381
|
grantedScopes,
|
|
378
|
-
accountInfo: accountInfo ??
|
|
382
|
+
accountInfo: accountInfo ?? parsedAccountIdentifier,
|
|
379
383
|
};
|
|
380
384
|
} catch (err: unknown) {
|
|
381
385
|
const message =
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Mutable mock state
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
let mockProvider: Record<string, unknown> | undefined;
|
|
8
|
+
let mockConnection: Record<string, unknown> | undefined;
|
|
9
|
+
let mockAccessToken: string | undefined;
|
|
10
|
+
let mockConfig: Record<string, unknown> = {};
|
|
11
|
+
let mockManagedProxyCtx = {
|
|
12
|
+
enabled: false,
|
|
13
|
+
platformBaseUrl: "",
|
|
14
|
+
assistantApiKey: "",
|
|
15
|
+
};
|
|
16
|
+
let mockAssistantId = "";
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Module mocks (must precede imports of the module under test)
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
mock.module("../util/logger.js", () => ({
|
|
23
|
+
getLogger: () =>
|
|
24
|
+
new Proxy({} as Record<string, unknown>, {
|
|
25
|
+
get: () => () => {},
|
|
26
|
+
}),
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
mock.module("./oauth-store.js", () => ({
|
|
30
|
+
getProvider: () => mockProvider,
|
|
31
|
+
getActiveConnection: (
|
|
32
|
+
_pk: string,
|
|
33
|
+
opts?: { clientId?: string; account?: string },
|
|
34
|
+
) => {
|
|
35
|
+
if (opts?.clientId && mockConnection?.clientId !== opts.clientId)
|
|
36
|
+
return undefined;
|
|
37
|
+
if (opts?.account && mockConnection?.accountInfo !== opts.account)
|
|
38
|
+
return undefined;
|
|
39
|
+
return mockConnection;
|
|
40
|
+
},
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
mock.module("../security/secure-keys.js", () => ({
|
|
44
|
+
getSecureKeyAsync: async () => mockAccessToken,
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
mock.module("../config/loader.js", () => ({
|
|
48
|
+
getConfig: () => mockConfig,
|
|
49
|
+
}));
|
|
50
|
+
|
|
51
|
+
mock.module("../config/env.js", () => ({
|
|
52
|
+
getPlatformAssistantId: () => mockAssistantId,
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
mock.module("../providers/managed-proxy/context.js", () => ({
|
|
56
|
+
resolveManagedProxyContext: async () => mockManagedProxyCtx,
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Import the module under test (after all mocks are registered)
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
import { BYOOAuthConnection } from "./byo-connection.js";
|
|
64
|
+
import { resolveOAuthConnection } from "./connection-resolver.js";
|
|
65
|
+
import { PlatformOAuthConnection } from "./platform-connection.js";
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Helpers
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
function setupDefaults(): void {
|
|
72
|
+
mockProvider = {
|
|
73
|
+
providerKey: "integration:google",
|
|
74
|
+
baseUrl: "https://gmail.googleapis.com/gmail/v1/users/me",
|
|
75
|
+
managedServiceConfigKey: null,
|
|
76
|
+
};
|
|
77
|
+
mockConnection = {
|
|
78
|
+
id: "conn-1",
|
|
79
|
+
providerKey: "integration:google",
|
|
80
|
+
oauthAppId: "app-1",
|
|
81
|
+
accountInfo: "user@example.com",
|
|
82
|
+
grantedScopes: JSON.stringify(["scope-a", "scope-b"]),
|
|
83
|
+
status: "active",
|
|
84
|
+
clientId: "client-1",
|
|
85
|
+
};
|
|
86
|
+
mockAccessToken = "tok-valid";
|
|
87
|
+
mockConfig = {
|
|
88
|
+
services: {
|
|
89
|
+
inference: {
|
|
90
|
+
mode: "your-own",
|
|
91
|
+
provider: "anthropic",
|
|
92
|
+
model: "claude-opus-4-6",
|
|
93
|
+
},
|
|
94
|
+
"image-generation": {
|
|
95
|
+
mode: "your-own",
|
|
96
|
+
provider: "gemini",
|
|
97
|
+
model: "gemini-3.1-flash-image-preview",
|
|
98
|
+
},
|
|
99
|
+
"web-search": { mode: "your-own", provider: "inference-provider-native" },
|
|
100
|
+
"google-oauth": { mode: "managed" },
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
mockManagedProxyCtx = {
|
|
104
|
+
enabled: true,
|
|
105
|
+
platformBaseUrl: "https://platform.example.com",
|
|
106
|
+
assistantApiKey: "sk-test-key",
|
|
107
|
+
};
|
|
108
|
+
mockAssistantId = "asst-123";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Tests
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
describe("resolveOAuthConnection", () => {
|
|
116
|
+
beforeEach(() => {
|
|
117
|
+
setupDefaults();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("returns BYOOAuthConnection when provider has no managedServiceConfigKey", async () => {
|
|
121
|
+
const result = await resolveOAuthConnection("integration:google");
|
|
122
|
+
expect(result).toBeInstanceOf(BYOOAuthConnection);
|
|
123
|
+
expect(result.id).toBe("conn-1");
|
|
124
|
+
expect(result.providerKey).toBe("integration:google");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("returns PlatformOAuthConnection when managed mode is active", async () => {
|
|
128
|
+
mockProvider!.managedServiceConfigKey = "google-oauth";
|
|
129
|
+
|
|
130
|
+
const result = await resolveOAuthConnection("integration:google");
|
|
131
|
+
expect(result).toBeInstanceOf(PlatformOAuthConnection);
|
|
132
|
+
expect(result.id).toBe("integration:google");
|
|
133
|
+
expect(result.providerKey).toBe("integration:google");
|
|
134
|
+
expect(result.accountInfo).toBeNull();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("passes account through to PlatformOAuthConnection", async () => {
|
|
138
|
+
mockProvider!.managedServiceConfigKey = "google-oauth";
|
|
139
|
+
|
|
140
|
+
const result = await resolveOAuthConnection("integration:google", {
|
|
141
|
+
account: "user@example.com",
|
|
142
|
+
});
|
|
143
|
+
expect(result).toBeInstanceOf(PlatformOAuthConnection);
|
|
144
|
+
expect(result.accountInfo).toBe("user@example.com");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("returns BYOOAuthConnection when service config mode is your-own", async () => {
|
|
148
|
+
mockProvider!.managedServiceConfigKey = "google-oauth";
|
|
149
|
+
(mockConfig.services as Record<string, unknown>)["google-oauth"] = {
|
|
150
|
+
mode: "your-own",
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const result = await resolveOAuthConnection("integration:google");
|
|
154
|
+
expect(result).toBeInstanceOf(BYOOAuthConnection);
|
|
155
|
+
expect(result.id).toBe("conn-1");
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test("managed path does not require a local connection row", async () => {
|
|
159
|
+
mockProvider!.managedServiceConfigKey = "google-oauth";
|
|
160
|
+
mockConnection = undefined;
|
|
161
|
+
mockAccessToken = undefined;
|
|
162
|
+
|
|
163
|
+
const result = await resolveOAuthConnection("integration:google");
|
|
164
|
+
expect(result).toBeInstanceOf(PlatformOAuthConnection);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("managed path ignores clientId option", async () => {
|
|
168
|
+
mockProvider!.managedServiceConfigKey = "google-oauth";
|
|
169
|
+
|
|
170
|
+
const result = await resolveOAuthConnection("integration:google", {
|
|
171
|
+
clientId: "some-client-id",
|
|
172
|
+
});
|
|
173
|
+
expect(result).toBeInstanceOf(PlatformOAuthConnection);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("BYO path narrows by clientId when provided", async () => {
|
|
177
|
+
const result = await resolveOAuthConnection("integration:google", {
|
|
178
|
+
clientId: "client-1",
|
|
179
|
+
});
|
|
180
|
+
expect(result).toBeInstanceOf(BYOOAuthConnection);
|
|
181
|
+
expect(result.id).toBe("conn-1");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("BYO path returns no credential when clientId does not match", async () => {
|
|
185
|
+
await expect(
|
|
186
|
+
resolveOAuthConnection("integration:google", {
|
|
187
|
+
clientId: "wrong-client",
|
|
188
|
+
}),
|
|
189
|
+
).rejects.toThrow(/No active OAuth connection found/);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
@@ -1,72 +1,100 @@
|
|
|
1
|
+
import { getPlatformAssistantId } from "../config/env.js";
|
|
2
|
+
import { getConfig } from "../config/loader.js";
|
|
3
|
+
import { type Services, ServicesSchema } from "../config/schemas/services.js";
|
|
4
|
+
import { resolveManagedProxyContext } from "../providers/managed-proxy/context.js";
|
|
1
5
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
2
6
|
import { BYOOAuthConnection } from "./byo-connection.js";
|
|
3
7
|
import type { OAuthConnection } from "./connection.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import { getActiveConnection, getProvider } from "./oauth-store.js";
|
|
9
|
+
import { PlatformOAuthConnection } from "./platform-connection.js";
|
|
10
|
+
|
|
11
|
+
export interface ResolveOAuthConnectionOptions {
|
|
12
|
+
/** OAuth app client ID — narrows to a specific app when multiple BYO apps
|
|
13
|
+
* exist for the same provider. */
|
|
14
|
+
clientId?: string;
|
|
15
|
+
/** Account identifier (e.g. email, username) — disambiguates when multiple
|
|
16
|
+
* accounts are connected for the same provider. Best-effort: not guaranteed
|
|
17
|
+
* to be present on all connections. */
|
|
18
|
+
account?: string;
|
|
19
|
+
}
|
|
10
20
|
|
|
11
21
|
/**
|
|
12
|
-
* Resolve an OAuthConnection for a given
|
|
22
|
+
* Resolve an OAuthConnection for a given provider.
|
|
23
|
+
*
|
|
24
|
+
* Managed providers (where the service config `mode` is `"managed"`) are
|
|
25
|
+
* routed through the platform proxy with no local state required.
|
|
13
26
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* active connection.
|
|
27
|
+
* BYO providers resolve from the local SQLite oauth-store and require an
|
|
28
|
+
* active connection row and a stored access token.
|
|
17
29
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
30
|
+
* @param providerKey - Provider identifier (e.g. "integration:google").
|
|
31
|
+
* Maps to the `provider_key` primary key in the `oauth_providers` table.
|
|
32
|
+
* @param options.clientId - Optional OAuth app client ID. When multiple BYO
|
|
33
|
+
* apps exist for the same provider, narrows the connection lookup to the
|
|
34
|
+
* app matching this client ID. Ignored for managed providers.
|
|
35
|
+
* @param options.account - Optional account identifier to disambiguate
|
|
36
|
+
* multi-account connections.
|
|
20
37
|
*/
|
|
21
38
|
export async function resolveOAuthConnection(
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
providerKey: string,
|
|
40
|
+
options?: ResolveOAuthConnectionOptions,
|
|
24
41
|
): Promise<OAuthConnection> {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
const { clientId, account } = options ?? {};
|
|
43
|
+
const provider = getProvider(providerKey);
|
|
44
|
+
const managedKey = provider?.managedServiceConfigKey;
|
|
45
|
+
|
|
46
|
+
if (managedKey && managedKey in ServicesSchema.shape) {
|
|
47
|
+
const services: Services = getConfig().services;
|
|
48
|
+
if (services[managedKey as keyof Services].mode === "managed") {
|
|
49
|
+
const ctx = await resolveManagedProxyContext();
|
|
50
|
+
const assistantId = getPlatformAssistantId();
|
|
51
|
+
return new PlatformOAuthConnection({
|
|
52
|
+
id: providerKey,
|
|
53
|
+
providerKey,
|
|
54
|
+
externalId: providerKey,
|
|
55
|
+
accountInfo: account ?? null,
|
|
56
|
+
assistantId,
|
|
57
|
+
platformBaseUrl: ctx.platformBaseUrl,
|
|
58
|
+
apiKey: ctx.assistantApiKey,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// BYO path — requires a local connection row, access token, and base URL.
|
|
64
|
+
const conn = getActiveConnection(providerKey, { clientId, account });
|
|
28
65
|
if (!conn) {
|
|
66
|
+
const filters = [
|
|
67
|
+
account && `account "${account}"`,
|
|
68
|
+
clientId && `client ID "${clientId}"`,
|
|
69
|
+
].filter(Boolean);
|
|
70
|
+
const qualifier = filters.length
|
|
71
|
+
? ` matching ${filters.join(" and ")}`
|
|
72
|
+
: "";
|
|
29
73
|
throw new Error(
|
|
30
|
-
`No
|
|
74
|
+
`No active OAuth connection found for "${providerKey}"${qualifier}. Connect the service first with oauth2_connect.`,
|
|
31
75
|
);
|
|
32
76
|
}
|
|
33
77
|
|
|
34
78
|
const accessToken = await getSecureKeyAsync(
|
|
35
79
|
`oauth_connection/${conn.id}/access_token`,
|
|
36
80
|
);
|
|
37
|
-
|
|
38
81
|
if (!accessToken) {
|
|
39
82
|
throw new Error(
|
|
40
|
-
`
|
|
83
|
+
`OAuth connection for "${providerKey}" exists but has no access token. Re-authorize with oauth2_connect.`,
|
|
41
84
|
);
|
|
42
85
|
}
|
|
43
86
|
|
|
44
|
-
// Look up the provider by credentialService first; fall back to the
|
|
45
|
-
// connection's app's canonical providerKey so custom credential_service
|
|
46
|
-
// overrides (e.g. "integration:github-work") still resolve to the well-known
|
|
47
|
-
// provider's base URL. We traverse conn -> oauthApp -> providerKey because
|
|
48
|
-
// conn.providerKey equals credentialService (getConnectionByProvider queries
|
|
49
|
-
// WHERE providerKey = credentialService), whereas the app's providerKey is a
|
|
50
|
-
// foreign key to the oauthProviders table.
|
|
51
|
-
const provider =
|
|
52
|
-
getProvider(credentialService) ??
|
|
53
|
-
getProvider(getApp(conn.oauthAppId)?.providerKey ?? "");
|
|
54
87
|
const baseUrl = provider?.baseUrl;
|
|
55
|
-
|
|
56
88
|
if (!baseUrl) {
|
|
57
|
-
throw new Error(
|
|
89
|
+
throw new Error(
|
|
90
|
+
`OAuth provider "${providerKey}" has no base URL configured. Check provider setup.`,
|
|
91
|
+
);
|
|
58
92
|
}
|
|
59
93
|
|
|
60
|
-
const grantedScopes: string[] = conn.grantedScopes
|
|
61
|
-
? JSON.parse(conn.grantedScopes)
|
|
62
|
-
: [];
|
|
63
|
-
|
|
64
94
|
return new BYOOAuthConnection({
|
|
65
95
|
id: conn.id,
|
|
66
96
|
providerKey: conn.providerKey,
|
|
67
97
|
baseUrl,
|
|
68
98
|
accountInfo: conn.accountInfo,
|
|
69
|
-
grantedScopes,
|
|
70
|
-
credentialService,
|
|
71
99
|
});
|
|
72
100
|
}
|