@vellumai/assistant 0.8.0 → 0.8.1
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/AGENTS.md +11 -0
- package/Dockerfile +5 -4
- package/README.md +2 -2
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +23 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +148 -127
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +628 -10
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +19 -3
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +303 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +334 -86
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +22 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot-time backfill: migrates existing config.json from the legacy
|
|
3
|
+
* `provider` + `source` model to the new `provider_connection` model.
|
|
4
|
+
*
|
|
5
|
+
* Walks three locations in `llm.*` on every boot:
|
|
6
|
+
* - `llm.default` — the base profile every dispatch falls back on
|
|
7
|
+
* - `llm.profiles.*` — named alternate profiles (fast/balanced/...)
|
|
8
|
+
* - `llm.callSites.*` — per-call-site overrides with bare `provider`
|
|
9
|
+
*
|
|
10
|
+
* Idempotent: any object that already has `provider_connection` is skipped.
|
|
11
|
+
* Only modifies config.json when at least one location needs updating.
|
|
12
|
+
*
|
|
13
|
+
* The `default` and `callSites` walks were added alongside Phase 1.1 of the
|
|
14
|
+
* post-v1 inference-providers cleanup: dispatch now throws on missing
|
|
15
|
+
* `provider_connection` instead of silently falling back to legacy
|
|
16
|
+
* `getProvider(name)`, so existing configs need an explicit field on the
|
|
17
|
+
* default profile and on any legacy bare-`provider` callsite override.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
21
|
+
import type { DrizzleDb } from "../../memory/db-connection.js";
|
|
22
|
+
import { credentialKey } from "../../security/credential-key.js";
|
|
23
|
+
import { getLogger } from "../../util/logger.js";
|
|
24
|
+
import { createConnection, getConnection, seedCanonicalConnections } from "./connections.js";
|
|
25
|
+
|
|
26
|
+
const log = getLogger("provider-connections-backfill");
|
|
27
|
+
|
|
28
|
+
// Providers that support the managed (platform) auth type.
|
|
29
|
+
const MANAGED_PROVIDERS = new Set(["anthropic", "openai", "gemini"]);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Seed canonical provider_connections and backfill any legacy config locations
|
|
33
|
+
* that pre-date the connection field.
|
|
34
|
+
*
|
|
35
|
+
* Runs on every daemon boot — both halves are idempotent and cheap
|
|
36
|
+
* (O(profiles + callSites), typically ≤20 entries total). Designed to:
|
|
37
|
+
* - propagate new canonical connections as they're added in future versions
|
|
38
|
+
* - self-heal manual config.json edits that drop the connection field
|
|
39
|
+
*
|
|
40
|
+
* Steps:
|
|
41
|
+
* 1. Upsert canonical connections.
|
|
42
|
+
* 2. Walk `llm.default`, `llm.profiles.*`, `llm.callSites.*` in config.json.
|
|
43
|
+
* 3. For each entry without `provider_connection`, derive one from the
|
|
44
|
+
* entry's `provider` field + the global inference mode and write it back.
|
|
45
|
+
* 4. Save config.json if any entry was updated.
|
|
46
|
+
*/
|
|
47
|
+
export function runProviderConnectionsBackfill(db: DrizzleDb): void {
|
|
48
|
+
try {
|
|
49
|
+
seedCanonicalConnections(db);
|
|
50
|
+
backfillConfigProfiles(db);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
log.error({ err }, "provider_connections backfill failed — will retry on next boot");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function backfillConfigProfiles(db: DrizzleDb): void {
|
|
57
|
+
const raw = loadRawConfig();
|
|
58
|
+
const llm = raw.llm as Record<string, unknown> | undefined;
|
|
59
|
+
if (!llm) return;
|
|
60
|
+
|
|
61
|
+
const isPlatform =
|
|
62
|
+
process.env.IS_PLATFORM === "true" || process.env.IS_PLATFORM === "1";
|
|
63
|
+
const globalMode = isPlatform ? "managed" : "your-own";
|
|
64
|
+
|
|
65
|
+
let changed = false;
|
|
66
|
+
|
|
67
|
+
// 1. The default profile — every dispatch path's terminal fallback.
|
|
68
|
+
const defaultProfile = llm.default as Record<string, unknown> | undefined;
|
|
69
|
+
if (defaultProfile && typeof defaultProfile === "object") {
|
|
70
|
+
if (ensureProviderConnection(defaultProfile, "<llm.default>", db, globalMode)) {
|
|
71
|
+
llm.default = defaultProfile;
|
|
72
|
+
changed = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 2. Named alternate profiles.
|
|
77
|
+
const profiles = llm.profiles as Record<string, unknown> | undefined;
|
|
78
|
+
if (profiles && typeof profiles === "object") {
|
|
79
|
+
for (const [profileName, profileVal] of Object.entries(profiles)) {
|
|
80
|
+
const profile = profileVal as Record<string, unknown>;
|
|
81
|
+
if (!profile || typeof profile !== "object") continue;
|
|
82
|
+
if (ensureProviderConnection(profile, profileName, db, globalMode)) {
|
|
83
|
+
profiles[profileName] = profile;
|
|
84
|
+
changed = true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (changed) llm.profiles = profiles;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 3. Per-call-site overrides. Only legacy entries with a bare `provider`
|
|
91
|
+
// field need backfill — entries that just point at a `profile` already
|
|
92
|
+
// inherit `provider_connection` from there.
|
|
93
|
+
const callSites = llm.callSites as Record<string, unknown> | undefined;
|
|
94
|
+
if (callSites && typeof callSites === "object") {
|
|
95
|
+
for (const [callSiteName, callSiteVal] of Object.entries(callSites)) {
|
|
96
|
+
const callSite = callSiteVal as Record<string, unknown>;
|
|
97
|
+
if (!callSite || typeof callSite !== "object") continue;
|
|
98
|
+
// Only touch overrides that explicitly set `provider` — the typical
|
|
99
|
+
// case is `{profile: "fast"}`, which has no provider and inherits
|
|
100
|
+
// through `resolveCallSiteConfig` deep-merge.
|
|
101
|
+
if (callSite.provider == null) continue;
|
|
102
|
+
if (
|
|
103
|
+
ensureProviderConnection(
|
|
104
|
+
callSite,
|
|
105
|
+
`<llm.callSites.${callSiteName}>`,
|
|
106
|
+
db,
|
|
107
|
+
globalMode,
|
|
108
|
+
)
|
|
109
|
+
) {
|
|
110
|
+
callSites[callSiteName] = callSite;
|
|
111
|
+
changed = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (changed) llm.callSites = callSites;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (changed) {
|
|
118
|
+
raw.llm = llm;
|
|
119
|
+
saveRawConfig(raw);
|
|
120
|
+
log.info("Saved config.json after provider_connection backfill");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Ensure a profile-shaped config object has `provider_connection` set.
|
|
126
|
+
*
|
|
127
|
+
* Mutates `entry` in place when it has `provider` but no `provider_connection`,
|
|
128
|
+
* deriving the canonical connection name from the global auth mode. If a
|
|
129
|
+
* `*-personal` connection is needed and doesn't yet exist in the DB, this
|
|
130
|
+
* also creates it (lazy bootstrap of user-mode credential rows).
|
|
131
|
+
*
|
|
132
|
+
* Returns `true` if the entry was changed, `false` otherwise.
|
|
133
|
+
*/
|
|
134
|
+
function ensureProviderConnection(
|
|
135
|
+
entry: Record<string, unknown>,
|
|
136
|
+
entryLabel: string,
|
|
137
|
+
db: DrizzleDb,
|
|
138
|
+
globalMode: string,
|
|
139
|
+
): boolean {
|
|
140
|
+
// Treat empty/whitespace strings the same as missing — `resolveDefaultProvider`
|
|
141
|
+
// (and friends) use a falsy check on the field, so a manually cleared
|
|
142
|
+
// `provider_connection: ""` would otherwise skip backfill and then hard-throw
|
|
143
|
+
// at runtime. Self-heal those alongside null/undefined.
|
|
144
|
+
const existing = entry.provider_connection;
|
|
145
|
+
const hasValid =
|
|
146
|
+
typeof existing === "string" && existing.trim() !== "";
|
|
147
|
+
if (hasValid) return false;
|
|
148
|
+
|
|
149
|
+
const provider = entry.provider as string | undefined;
|
|
150
|
+
if (!provider) return false;
|
|
151
|
+
|
|
152
|
+
let connectionName: string;
|
|
153
|
+
|
|
154
|
+
if (globalMode === "managed" && MANAGED_PROVIDERS.has(provider)) {
|
|
155
|
+
connectionName = `${provider}-managed`;
|
|
156
|
+
} else {
|
|
157
|
+
// "your-own" path (or provider not managed-supported): ensure a
|
|
158
|
+
// personal connection exists. Ollama is keyless, so it gets
|
|
159
|
+
// `auth: { type: "none" }`; everything else gets an api_key
|
|
160
|
+
// pointing at the conventional credential slot.
|
|
161
|
+
connectionName = `${provider}-personal`;
|
|
162
|
+
if (!getConnection(db, connectionName)) {
|
|
163
|
+
const isKeyless = provider === "ollama";
|
|
164
|
+
const credName = credentialKey(provider, "api_key");
|
|
165
|
+
const result = createConnection(db, {
|
|
166
|
+
name: connectionName,
|
|
167
|
+
provider,
|
|
168
|
+
auth: isKeyless
|
|
169
|
+
? { type: "none" }
|
|
170
|
+
: { type: "api_key", credential: credName },
|
|
171
|
+
});
|
|
172
|
+
if (!result.ok) {
|
|
173
|
+
log.warn(
|
|
174
|
+
{ entry: entryLabel, provider, error: result.error },
|
|
175
|
+
"Failed to create personal connection during backfill; skipping entry",
|
|
176
|
+
);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
log.info(
|
|
180
|
+
{
|
|
181
|
+
connectionName,
|
|
182
|
+
provider,
|
|
183
|
+
credential: isKeyless ? null : credName,
|
|
184
|
+
},
|
|
185
|
+
"Created personal connection during backfill",
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
entry.provider_connection = connectionName;
|
|
191
|
+
log.info(
|
|
192
|
+
{ entry: entryLabel, connectionName },
|
|
193
|
+
"Backfilled provider_connection",
|
|
194
|
+
);
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { and, eq, isNull } from "drizzle-orm";
|
|
2
|
+
|
|
3
|
+
import type { DrizzleDb } from "../../memory/db-connection.js";
|
|
4
|
+
import { providerConnections } from "../../memory/schema/inference.js";
|
|
5
|
+
import { clearConnectionProviderCache } from "../registry.js";
|
|
6
|
+
import {
|
|
7
|
+
type Auth,
|
|
8
|
+
AuthSchema,
|
|
9
|
+
type ConnectionProvider,
|
|
10
|
+
ConnectionProviderSchema,
|
|
11
|
+
type ConnectionStatus,
|
|
12
|
+
ConnectionStatusSchema,
|
|
13
|
+
type ProviderConnection,
|
|
14
|
+
VALID_CONNECTION_PROVIDERS,
|
|
15
|
+
} from "./auth.js";
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Read
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
export function listConnections(
|
|
22
|
+
db: DrizzleDb,
|
|
23
|
+
filter?: { provider?: string },
|
|
24
|
+
): ProviderConnection[] {
|
|
25
|
+
const rows = filter?.provider
|
|
26
|
+
? db.select().from(providerConnections).where(eq(providerConnections.provider, filter.provider)).all()
|
|
27
|
+
: db.select().from(providerConnections).all();
|
|
28
|
+
|
|
29
|
+
return rows.flatMap((row) => {
|
|
30
|
+
const auth = AuthSchema.safeParse(JSON.parse(row.auth));
|
|
31
|
+
if (!auth.success) return [];
|
|
32
|
+
const provider = ConnectionProviderSchema.safeParse(row.provider);
|
|
33
|
+
if (!provider.success) return [];
|
|
34
|
+
const statusResult = ConnectionStatusSchema.safeParse(row.status);
|
|
35
|
+
const status: ConnectionStatus = statusResult.success ? statusResult.data : "active";
|
|
36
|
+
return [{
|
|
37
|
+
...row,
|
|
38
|
+
auth: auth.data,
|
|
39
|
+
provider: provider.data,
|
|
40
|
+
status,
|
|
41
|
+
label: row.label ?? null,
|
|
42
|
+
isManaged: MANAGED_CONNECTION_NAMES.has(row.name),
|
|
43
|
+
}];
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function getConnection(
|
|
48
|
+
db: DrizzleDb,
|
|
49
|
+
name: string,
|
|
50
|
+
): ProviderConnection | null {
|
|
51
|
+
const row = db
|
|
52
|
+
.select()
|
|
53
|
+
.from(providerConnections)
|
|
54
|
+
.where(eq(providerConnections.name, name))
|
|
55
|
+
.get();
|
|
56
|
+
|
|
57
|
+
if (!row) return null;
|
|
58
|
+
const auth = AuthSchema.safeParse(JSON.parse(row.auth));
|
|
59
|
+
if (!auth.success) return null;
|
|
60
|
+
const provider = ConnectionProviderSchema.safeParse(row.provider);
|
|
61
|
+
if (!provider.success) return null;
|
|
62
|
+
const statusResult = ConnectionStatusSchema.safeParse(row.status);
|
|
63
|
+
const status: ConnectionStatus = statusResult.success ? statusResult.data : "active";
|
|
64
|
+
return {
|
|
65
|
+
...row,
|
|
66
|
+
auth: auth.data,
|
|
67
|
+
provider: provider.data,
|
|
68
|
+
status,
|
|
69
|
+
label: row.label ?? null,
|
|
70
|
+
isManaged: MANAGED_CONNECTION_NAMES.has(row.name),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Write
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
export type CreateConnectionInput = {
|
|
79
|
+
name: string;
|
|
80
|
+
provider: string;
|
|
81
|
+
auth: Auth;
|
|
82
|
+
status?: ConnectionStatus;
|
|
83
|
+
label?: string | null;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export type UpdateConnectionInput = {
|
|
87
|
+
auth: Auth;
|
|
88
|
+
status?: ConnectionStatus;
|
|
89
|
+
label?: string | null;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export type ConnectionCreateError =
|
|
93
|
+
| { code: "already_exists" }
|
|
94
|
+
| { code: "invalid_provider"; provider: string }
|
|
95
|
+
| { code: "invalid_auth" };
|
|
96
|
+
|
|
97
|
+
export type ConnectionUpdateError =
|
|
98
|
+
| { code: "not_found" }
|
|
99
|
+
| { code: "invalid_auth" };
|
|
100
|
+
|
|
101
|
+
export type ConnectionDeleteError =
|
|
102
|
+
| { code: "not_found" }
|
|
103
|
+
| { code: "has_references"; count: number };
|
|
104
|
+
|
|
105
|
+
export function createConnection(
|
|
106
|
+
db: DrizzleDb,
|
|
107
|
+
input: CreateConnectionInput,
|
|
108
|
+
): { ok: true; connection: ProviderConnection } | { ok: false; error: ConnectionCreateError } {
|
|
109
|
+
if (!VALID_CONNECTION_PROVIDERS.includes(input.provider as never)) {
|
|
110
|
+
return { ok: false, error: { code: "invalid_provider", provider: input.provider } };
|
|
111
|
+
}
|
|
112
|
+
// Safe cast: VALID_CONNECTION_PROVIDERS.includes() guards above.
|
|
113
|
+
const provider = input.provider as ConnectionProvider;
|
|
114
|
+
|
|
115
|
+
const authResult = AuthSchema.safeParse(input.auth);
|
|
116
|
+
if (!authResult.success) {
|
|
117
|
+
return { ok: false, error: { code: "invalid_auth" } };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const existing = db
|
|
121
|
+
.select({ name: providerConnections.name })
|
|
122
|
+
.from(providerConnections)
|
|
123
|
+
.where(eq(providerConnections.name, input.name))
|
|
124
|
+
.get();
|
|
125
|
+
if (existing) {
|
|
126
|
+
return { ok: false, error: { code: "already_exists" } };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const status = input.status ?? "active";
|
|
130
|
+
const label = input.label ?? null;
|
|
131
|
+
|
|
132
|
+
const now = Date.now();
|
|
133
|
+
db.insert(providerConnections).values({
|
|
134
|
+
name: input.name,
|
|
135
|
+
provider,
|
|
136
|
+
auth: JSON.stringify(authResult.data),
|
|
137
|
+
status,
|
|
138
|
+
label,
|
|
139
|
+
createdAt: now,
|
|
140
|
+
updatedAt: now,
|
|
141
|
+
}).run();
|
|
142
|
+
|
|
143
|
+
// Invalidate per-connection adapter cache so subsequent dispatch
|
|
144
|
+
// resolves the freshly-inserted row's auth.
|
|
145
|
+
clearConnectionProviderCache();
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
ok: true,
|
|
149
|
+
connection: {
|
|
150
|
+
name: input.name,
|
|
151
|
+
provider,
|
|
152
|
+
auth: authResult.data,
|
|
153
|
+
status,
|
|
154
|
+
label,
|
|
155
|
+
createdAt: now,
|
|
156
|
+
updatedAt: now,
|
|
157
|
+
isManaged: MANAGED_CONNECTION_NAMES.has(input.name),
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function updateConnection(
|
|
163
|
+
db: DrizzleDb,
|
|
164
|
+
name: string,
|
|
165
|
+
input: UpdateConnectionInput,
|
|
166
|
+
): { ok: true; connection: ProviderConnection } | { ok: false; error: ConnectionUpdateError } {
|
|
167
|
+
const existing = getConnection(db, name);
|
|
168
|
+
if (!existing) {
|
|
169
|
+
return { ok: false, error: { code: "not_found" } };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const authResult = AuthSchema.safeParse(input.auth);
|
|
173
|
+
if (!authResult.success) {
|
|
174
|
+
return { ok: false, error: { code: "invalid_auth" } };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
const setClause: {
|
|
179
|
+
auth: string;
|
|
180
|
+
updatedAt: number;
|
|
181
|
+
status?: string;
|
|
182
|
+
label?: string | null;
|
|
183
|
+
} = { auth: JSON.stringify(authResult.data), updatedAt: now };
|
|
184
|
+
if (input.status !== undefined) setClause.status = input.status;
|
|
185
|
+
if (input.label !== undefined) setClause.label = input.label;
|
|
186
|
+
|
|
187
|
+
db.update(providerConnections)
|
|
188
|
+
.set(setClause)
|
|
189
|
+
.where(eq(providerConnections.name, name))
|
|
190
|
+
.run();
|
|
191
|
+
|
|
192
|
+
// Drop cached adapter built against the previous auth config.
|
|
193
|
+
clearConnectionProviderCache();
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
ok: true,
|
|
197
|
+
connection: {
|
|
198
|
+
...existing,
|
|
199
|
+
auth: authResult.data,
|
|
200
|
+
status: input.status !== undefined ? input.status : existing.status,
|
|
201
|
+
label: input.label !== undefined ? input.label : existing.label,
|
|
202
|
+
updatedAt: now,
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Delete a connection.
|
|
209
|
+
*
|
|
210
|
+
* `force`: when true, delete even if profiles reference it.
|
|
211
|
+
* When false, rejects if any profile in the provided profile names list
|
|
212
|
+
* references this connection.
|
|
213
|
+
*/
|
|
214
|
+
export function deleteConnection(
|
|
215
|
+
db: DrizzleDb,
|
|
216
|
+
name: string,
|
|
217
|
+
opts: { force?: boolean; referencingProfiles?: string[] } = {},
|
|
218
|
+
): { ok: true } | { ok: false; error: ConnectionDeleteError } {
|
|
219
|
+
const existing = db
|
|
220
|
+
.select({ name: providerConnections.name })
|
|
221
|
+
.from(providerConnections)
|
|
222
|
+
.where(eq(providerConnections.name, name))
|
|
223
|
+
.get();
|
|
224
|
+
|
|
225
|
+
if (!existing) {
|
|
226
|
+
return { ok: false, error: { code: "not_found" } };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (!opts.force && opts.referencingProfiles && opts.referencingProfiles.length > 0) {
|
|
230
|
+
return {
|
|
231
|
+
ok: false,
|
|
232
|
+
error: { code: "has_references", count: opts.referencingProfiles.length },
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
db.delete(providerConnections).where(eq(providerConnections.name, name)).run();
|
|
237
|
+
|
|
238
|
+
// Evict cached adapter for the deleted connection name.
|
|
239
|
+
clearConnectionProviderCache();
|
|
240
|
+
|
|
241
|
+
return { ok: true };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
// Seed canonical connections (upsert, used at boot time)
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
|
|
248
|
+
const CANONICAL_CONNECTIONS: Array<{
|
|
249
|
+
name: string;
|
|
250
|
+
provider: string;
|
|
251
|
+
auth: Auth;
|
|
252
|
+
label: string;
|
|
253
|
+
}> = [
|
|
254
|
+
{ name: "anthropic-managed", provider: "anthropic", auth: { type: "platform" }, label: "Anthropic" },
|
|
255
|
+
{ name: "openai-managed", provider: "openai", auth: { type: "platform" }, label: "OpenAI" },
|
|
256
|
+
{ name: "gemini-managed", provider: "gemini", auth: { type: "platform" }, label: "Google Gemini" },
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Names of the canonical Vellum-managed connections. These are seeded on every
|
|
261
|
+
* daemon boot via `seedCanonicalConnections` and represent the platform-managed
|
|
262
|
+
* inference route. They are write-protected at the route layer:
|
|
263
|
+
* - DELETE is blocked outright (would resurrect on next boot anyway, but
|
|
264
|
+
* blocking prevents a confusing delete → re-appear loop).
|
|
265
|
+
* - PATCH that changes `auth` is blocked (auth is locked to `{type:"platform"}`
|
|
266
|
+
* so any other value would be reverted on the next boot upsert).
|
|
267
|
+
* - PATCH that changes `label` and/or `status` is allowed — users may legitimately
|
|
268
|
+
* disable or relabel the managed connection. `status` is never touched by the
|
|
269
|
+
* boot upsert. `label` is seeded on initial INSERT and backfilled when null
|
|
270
|
+
* on subsequent boots so pre-seed installs pick up the default; a non-null
|
|
271
|
+
* user-customized label is preserved (see `seedCanonicalConnections`).
|
|
272
|
+
*
|
|
273
|
+
* Mirrors `MANAGED_PROFILE_NAMES` (config/seed-inference-profiles.ts).
|
|
274
|
+
*/
|
|
275
|
+
export const MANAGED_CONNECTION_NAMES: ReadonlySet<string> = new Set(
|
|
276
|
+
CANONICAL_CONNECTIONS.map((c) => c.name),
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Upsert the three canonical connections on every boot. Existing rows are
|
|
281
|
+
* updated to the latest provider/auth values so Vellum can push connection
|
|
282
|
+
* changes to customers in new releases.
|
|
283
|
+
*
|
|
284
|
+
* Label handling: the default label is seeded on initial INSERT so new
|
|
285
|
+
* installs render a human-friendly name in the connections list. The boot
|
|
286
|
+
* upsert deliberately leaves `label` alone on existing rows so user
|
|
287
|
+
* customization is preserved; the separate backfill step below assigns the
|
|
288
|
+
* default only when the existing row has `label IS NULL`, covering installs
|
|
289
|
+
* that pre-date the label seed.
|
|
290
|
+
*
|
|
291
|
+
* Status handling: the upsert never touches `status` so user customization
|
|
292
|
+
* is preserved across reboots. New rows default to `status: "active"` via the
|
|
293
|
+
* column default. Off-platform installs flip the three canonical rows to
|
|
294
|
+
* `status: "disabled"` ONCE at hatch time via
|
|
295
|
+
* `disableManagedConnectionsForByokHatch` (called from `seedInferenceProfiles`
|
|
296
|
+
* when `isHatch && !isPlatform`); subsequent boots leave whatever the user
|
|
297
|
+
* has chosen alone, so a post-hatch re-enable persists.
|
|
298
|
+
*/
|
|
299
|
+
export function seedCanonicalConnections(db: DrizzleDb): void {
|
|
300
|
+
const now = Date.now();
|
|
301
|
+
for (const { name, provider, auth, label } of CANONICAL_CONNECTIONS) {
|
|
302
|
+
db.insert(providerConnections)
|
|
303
|
+
.values({
|
|
304
|
+
name,
|
|
305
|
+
provider,
|
|
306
|
+
auth: JSON.stringify(auth),
|
|
307
|
+
label,
|
|
308
|
+
createdAt: now,
|
|
309
|
+
updatedAt: now,
|
|
310
|
+
})
|
|
311
|
+
.onConflictDoUpdate({
|
|
312
|
+
target: providerConnections.name,
|
|
313
|
+
set: {
|
|
314
|
+
provider,
|
|
315
|
+
auth: JSON.stringify(auth),
|
|
316
|
+
updatedAt: now,
|
|
317
|
+
},
|
|
318
|
+
})
|
|
319
|
+
.run();
|
|
320
|
+
|
|
321
|
+
// Backfill the default label on rows that pre-date label seeding so
|
|
322
|
+
// existing installs pick up the friendly name. Does not overwrite a
|
|
323
|
+
// user-set label.
|
|
324
|
+
db.update(providerConnections)
|
|
325
|
+
.set({ label, updatedAt: now })
|
|
326
|
+
.where(and(eq(providerConnections.name, name), isNull(providerConnections.label)))
|
|
327
|
+
.run();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Flip the three canonical managed connections to `status: "disabled"` at
|
|
333
|
+
* hatch time on BYOK (off-platform) installs.
|
|
334
|
+
*
|
|
335
|
+
* Why hatch-time only: managed connections need platform auth that a fresh
|
|
336
|
+
* BYOK user doesn't have yet, so surfacing them as enabled in the picker
|
|
337
|
+
* would let users pick an unusable option on day one. But this is a
|
|
338
|
+
* first-time-only default — the moment the user explicitly flips one
|
|
339
|
+
* back to active (e.g. after logging into Vellum), we never want a daemon
|
|
340
|
+
* restart to revert that. `seedCanonicalConnections` leaves `status` alone
|
|
341
|
+
* on the UPDATE path, and this helper is invoked ONLY from
|
|
342
|
+
* `seedInferenceProfiles`'s `isHatch && !isPlatform` branch. Subsequent
|
|
343
|
+
* non-hatch boots never call it.
|
|
344
|
+
*
|
|
345
|
+
* Idempotent: a second hatch (workspace reset) re-disables the rows, which
|
|
346
|
+
* is the right call — re-hatch means re-onboard.
|
|
347
|
+
*/
|
|
348
|
+
export function disableManagedConnectionsForByokHatch(db: DrizzleDb): void {
|
|
349
|
+
const now = Date.now();
|
|
350
|
+
for (const name of MANAGED_CONNECTION_NAMES) {
|
|
351
|
+
db.update(providerConnections)
|
|
352
|
+
.set({ status: "disabled", updatedAt: now })
|
|
353
|
+
.where(eq(providerConnections.name, name))
|
|
354
|
+
.run();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves an `Auth` config into a `ResolvedAuth` that adapters consume.
|
|
3
|
+
*
|
|
4
|
+
* Resolution rules:
|
|
5
|
+
* - api_key → fetch credential from vault → inject as bearer header
|
|
6
|
+
* - platform → build managed proxy URL and fetch the platform API key
|
|
7
|
+
* - none → pass through with no auth headers
|
|
8
|
+
* - oauth_subscription / service_account → reject (v2 not yet shipped)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
buildManagedBaseUrl,
|
|
13
|
+
resolveManagedProxyContext,
|
|
14
|
+
} from "../../providers/managed-proxy/context.js";
|
|
15
|
+
import { getSecureKeyAsync } from "../../security/secure-keys.js";
|
|
16
|
+
import type { Auth, ResolvedAuth } from "./auth.js";
|
|
17
|
+
|
|
18
|
+
export type ResolveAuthError =
|
|
19
|
+
| { code: "credential_not_found"; credential: string }
|
|
20
|
+
| { code: "platform_unavailable" }
|
|
21
|
+
| { code: "not_implemented"; authType: string };
|
|
22
|
+
|
|
23
|
+
export async function resolveAuth(
|
|
24
|
+
auth: Auth,
|
|
25
|
+
provider: string,
|
|
26
|
+
): Promise<{ ok: true; resolved: ResolvedAuth } | { ok: false; error: ResolveAuthError }> {
|
|
27
|
+
switch (auth.type) {
|
|
28
|
+
case "api_key": {
|
|
29
|
+
const value = await getSecureKeyAsync(auth.credential);
|
|
30
|
+
if (!value) {
|
|
31
|
+
return { ok: false, error: { code: "credential_not_found", credential: auth.credential } };
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
ok: true,
|
|
35
|
+
resolved: { kind: "header", headers: { Authorization: `Bearer ${value}` } },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
case "platform": {
|
|
40
|
+
const managedBaseUrl = await buildManagedBaseUrl(provider);
|
|
41
|
+
if (!managedBaseUrl) {
|
|
42
|
+
return { ok: false, error: { code: "platform_unavailable" } };
|
|
43
|
+
}
|
|
44
|
+
const ctx = await resolveManagedProxyContext();
|
|
45
|
+
return {
|
|
46
|
+
ok: true,
|
|
47
|
+
resolved: {
|
|
48
|
+
kind: "header",
|
|
49
|
+
headers: { Authorization: `Bearer ${ctx.assistantApiKey}` },
|
|
50
|
+
baseUrl: managedBaseUrl,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
case "none":
|
|
56
|
+
return { ok: true, resolved: { kind: "none" } };
|
|
57
|
+
|
|
58
|
+
case "oauth_subscription":
|
|
59
|
+
case "service_account":
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
error: { code: "not_implemented", authType: auth.type },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|