@vellumai/assistant 0.11.6 → 0.11.7-staging.2
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 +31 -19
- package/Dockerfile +1 -0
- package/docs/architecture/security.md +3 -3
- package/docs/flux-turn-detection-spike.md +8 -7
- package/docs/runbook-trusted-contacts.md +14 -0
- package/docs/stt-provider-onboarding.md +8 -4
- package/knip.json +1 -0
- package/node_modules/@vellumai/avatar-manifest/package.json +18 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/manifest.test.ts +173 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/read.test.ts +114 -0
- package/node_modules/@vellumai/avatar-manifest/src/index.ts +29 -0
- package/node_modules/@vellumai/avatar-manifest/src/layout.ts +18 -0
- package/node_modules/@vellumai/avatar-manifest/src/manifest.ts +156 -0
- package/node_modules/@vellumai/avatar-manifest/src/read.ts +109 -0
- package/node_modules/@vellumai/avatar-manifest/tsconfig.json +20 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/node_modules/@vellumai/ces-client/src/http-credentials.ts +161 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/shell.test.ts +56 -0
- package/node_modules/@vellumai/environments/src/shell.ts +65 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +32 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/inbound-event-kind.test.ts +82 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/plugin-admission-denied-contract.test.ts +56 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +18 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +5 -11
- package/node_modules/@vellumai/gateway-client/src/channel-permission-contract.ts +3 -1
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +9 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-event-kind.ts +75 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +17 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/plugin-admission-denied-contract.ts +47 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +11 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/openapi.yaml +419 -55
- package/package.json +4 -1
- package/scripts/sync-llm-catalog.ts +6 -0
- package/src/__tests__/approval-card-edit-inbound-handoff.test.ts +199 -0
- package/src/__tests__/approval-card-edit.test.ts +153 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +1 -1
- package/src/__tests__/available-skills.test.ts +54 -0
- package/src/__tests__/avatar-identity-sync.test.ts +5 -1
- package/src/__tests__/catalog-install-normalize.test.ts +9 -1
- package/src/__tests__/channel-policy.test.ts +1 -3
- package/src/__tests__/channel-readiness-discord.test.ts +9 -70
- package/src/__tests__/compactor-call-site-logging.test.ts +61 -0
- package/src/__tests__/config-loader-backfill.test.ts +69 -0
- package/src/__tests__/config-schema.test.ts +2 -3
- package/src/__tests__/conversation-agent-loop.test.ts +238 -0
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +44 -0
- package/src/__tests__/conversation-evictor.test.ts +19 -0
- package/src/__tests__/conversation-fork-referential.test.ts +73 -63
- package/src/__tests__/conversation-fork-retrospective.test.ts +99 -74
- package/src/__tests__/conversation-runtime-assembly.test.ts +23 -0
- package/src/__tests__/conversation-slash.test.ts +9 -0
- package/src/__tests__/conversation-title-service.test.ts +97 -0
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +16 -0
- package/src/__tests__/credential-broker-server-use.test.ts +0 -218
- package/src/__tests__/credential-broker.test.ts +43 -420
- package/src/__tests__/credential-record-write-through.test.ts +78 -0
- package/src/__tests__/credential-routes.test.ts +17 -1
- package/src/__tests__/credential-security-invariants.test.ts +8 -9
- package/src/__tests__/default-profile-catalog-fallback.test.ts +289 -0
- package/src/__tests__/delete-propagation.test.ts +92 -2
- package/src/__tests__/discord-callback-round-trip.test.ts +93 -0
- package/src/__tests__/discord-channel-config.test.ts +237 -0
- package/src/__tests__/edit-propagation.test.ts +42 -2
- package/src/__tests__/evict-conversations-for-reload.test.ts +51 -1
- package/src/__tests__/fallback-breaker.test.ts +1335 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +6 -0
- package/src/__tests__/guardian-card-withdrawal.test.ts +30 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -2
- package/src/__tests__/image-conversion.test.ts +38 -4
- package/src/__tests__/install-skill-routing.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +4 -0
- package/src/__tests__/llm-resolver.test.ts +74 -0
- package/src/__tests__/llm-schema-fallback-profile.test.ts +359 -0
- package/src/__tests__/managed-fallback-dispatch.test.ts +430 -0
- package/src/__tests__/managed-profile-guard.test.ts +28 -0
- package/src/__tests__/managed-speech-defaults.test.ts +196 -1
- package/src/__tests__/mcp-cli.test.ts +23 -1
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +43 -34
- package/src/__tests__/media-stream-stt-session.test.ts +2 -0
- package/src/__tests__/notification-decision-fallback.test.ts +106 -0
- package/src/__tests__/notification-discord-adapter.test.ts +162 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +95 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +6 -8
- package/src/__tests__/persist-unsendable-image.test.ts +3 -3
- package/src/__tests__/platform.test.ts +19 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -1
- package/src/__tests__/provider-catalog-visibility.test.ts +17 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +8 -1
- package/src/__tests__/provider-usage-tracking.test.ts +56 -0
- package/src/__tests__/require-fresh-approval.test.ts +5 -2
- package/src/__tests__/retry-fallback-escalation.test.ts +1093 -0
- package/src/__tests__/schedule-retry.test.ts +183 -4
- package/src/__tests__/scheduler-reuse-conversation.test.ts +6 -6
- package/src/__tests__/secret-routes-platform-proxy.test.ts +55 -0
- package/src/__tests__/skill-load-tool.test.ts +34 -0
- package/src/__tests__/skill-tool-factory.test.ts +6 -1
- package/src/__tests__/skill-tool-manifest.test.ts +20 -0
- package/src/__tests__/skills.test.ts +25 -0
- package/src/__tests__/subagent-manager-notify.test.ts +38 -0
- package/src/__tests__/terminal-tools.test.ts +2 -0
- package/src/__tests__/tool-approval-handler.test.ts +146 -2
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +108 -2
- package/src/__tests__/tool-audit.test.ts +111 -40
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +228 -18
- package/src/__tests__/ui-shape-teaching.test.ts +1 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +6 -2
- package/src/__tests__/voice-config-update.test.ts +43 -0
- package/src/__tests__/workspace-migration-147-rename-colliding-backup-profile-names.test.ts +480 -0
- package/src/__tests__/workspace-migration-148-strip-unsupported-fallback-profiles.test.ts +167 -0
- package/src/__tests__/workspace-migration-149-repoint-backup-profile-selections.test.ts +144 -0
- package/src/agent/loop.ts +31 -2
- package/src/approvals/guardian-card-withdrawal.ts +22 -0
- package/src/avatar/__tests__/ensure-raster.test.ts +291 -0
- package/src/avatar/avatar-manifest.ts +48 -100
- package/src/avatar/avatar-store.ts +7 -7
- package/src/avatar/ensure-raster.ts +146 -0
- package/src/avatar/resvg-lazy.test.ts +0 -1
- package/src/avatar/traits-png-sync.ts +9 -10
- package/src/background-wake/wake-intent-hooks.test.ts +0 -1
- package/src/backup/__tests__/paths.test.ts +6 -2
- package/src/backup/paths.ts +6 -4
- package/src/bundler/app-compiler.ts +2 -2
- package/src/bundler/compiler-tools.test.ts +36 -0
- package/src/bundler/compiler-tools.ts +54 -18
- package/src/calls/__tests__/telephony-synthesis-language.test.ts +81 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +57 -0
- package/src/calls/media-stream-stt-session.ts +2 -1
- package/src/calls/telephony-synthesis-language.ts +13 -5
- package/src/calls/voice-session-bridge.ts +19 -4
- package/src/channels/config.ts +23 -12
- package/src/cli/AGENTS.md +3 -1
- package/src/cli/commands/backup.help.ts +10 -13
- package/src/cli/commands/contacts.help.ts +16 -4
- package/src/cli/commands/contacts.ts +5 -1
- package/src/cli/commands/credentials.help.ts +1 -1
- package/src/cli/commands/inference-providers.ts +18 -53
- package/src/cli/commands/mcp.help.ts +6 -5
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/memory/memory-retrospective.ts +1 -0
- package/src/cli/commands/stt.help.ts +2 -2
- package/src/config/__tests__/backup-schema.test.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +83 -2
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +1 -1
- package/src/config/__tests__/memory-retrospective-schema.test.ts +12 -15
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +9 -6
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +3 -1
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +16 -15
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +2 -1
- package/src/config/bundled-skills/settings/TOOLS.json +11 -5
- package/src/config/bundled-skills/settings/tools/open-system-settings.test.ts +85 -0
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +33 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +54 -3
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +1 -1
- package/src/config/default-profile-catalog.ts +195 -10
- package/src/config/default-profile-names.ts +41 -0
- package/src/config/feature-flag-registry.json +34 -2
- package/src/config/inference-profile-validation.ts +11 -2
- package/src/config/llm-resolver.ts +25 -0
- package/src/config/loader.ts +3 -0
- package/src/config/managed-speech-defaults.ts +160 -10
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/live-voice.test.ts +7 -6
- package/src/config/schemas/__tests__/stt.test.ts +94 -0
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/channels.ts +32 -0
- package/src/config/schemas/live-voice.ts +13 -4
- package/src/config/schemas/llm.ts +263 -15
- package/src/config/schemas/mcp.ts +10 -2
- package/src/config/schemas/memory-retrospective.ts +1 -19
- package/src/config/schemas/services.ts +24 -0
- package/src/config/schemas/stt.ts +128 -5
- package/src/config/seed-inference-profiles.ts +32 -3
- package/src/config/skill-state.ts +5 -0
- package/src/config/skills.ts +21 -0
- package/src/contacts/notify-contacts-changed.ts +5 -2
- package/src/context/compactor.ts +74 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +138 -1
- package/src/daemon/config-watcher.ts +2 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -0
- package/src/daemon/conversation-agent-loop.ts +86 -10
- package/src/daemon/conversation-error.ts +25 -0
- package/src/daemon/conversation-evictor.ts +2 -4
- package/src/daemon/conversation-runtime-assembly.ts +19 -7
- package/src/daemon/conversation-skill-tools.ts +5 -1
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-store.ts +8 -1
- package/src/daemon/conversation-tool-setup.ts +37 -0
- package/src/daemon/conversation.ts +0 -4
- package/src/daemon/handlers/channel-config-result.ts +30 -0
- package/src/daemon/handlers/config-discord-channel.ts +301 -0
- package/src/daemon/handlers/config-ingress.ts +9 -0
- package/src/daemon/handlers/config-slack-channel.ts +13 -15
- package/src/daemon/handlers/config-telegram.ts +2 -5
- package/src/daemon/handlers/conversations.ts +0 -2
- package/src/daemon/handlers/skills.ts +25 -7
- package/src/daemon/lifecycle.ts +3 -1
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/tool-setup-types.ts +5 -3
- package/src/daemon/trust-context-types.test.ts +33 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +58 -4
- package/src/live-voice/__tests__/live-voice-managed-speech-fallback.test.ts +8 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +73 -11
- package/src/live-voice/__tests__/live-voice-session-preflight.test.ts +148 -2
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +64 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +3 -0
- package/src/live-voice/__tests__/live-voice-text-turn.test.ts +391 -0
- package/src/live-voice/__tests__/protocol.test.ts +224 -0
- package/src/live-voice/live-voice-credential-preflight.ts +5 -1
- package/src/live-voice/live-voice-session-manager.ts +39 -2
- package/src/live-voice/live-voice-session.ts +224 -9
- package/src/live-voice/protocol.ts +187 -1
- package/src/messaging/providers/discord/api.ts +2 -1
- package/src/messaging/providers/discord/withdraw.ts +62 -0
- package/src/messaging/read-provider-metadata.ts +32 -0
- package/src/monitoring/__tests__/file-descriptors.test.ts +32 -0
- package/src/monitoring/__tests__/process-memory.test.ts +34 -1
- package/src/monitoring/db-integrity-sample.ts +1 -0
- package/src/monitoring/file-descriptors.ts +39 -6
- package/src/monitoring/process-memory.ts +37 -5
- package/src/monitoring/resource-sampler.ts +25 -8
- package/src/notifications/__tests__/activity-failed-dedupe.test.ts +161 -0
- package/src/notifications/__tests__/background-failure-signal.test.ts +107 -0
- package/src/notifications/__tests__/connected-channels.test.ts +12 -0
- package/src/notifications/__tests__/copy-composer.test.ts +83 -0
- package/src/notifications/__tests__/destination-resolver.test.ts +38 -0
- package/src/notifications/activity-failed-dedupe.ts +95 -0
- package/src/notifications/adapters/discord.ts +132 -0
- package/src/notifications/adapters/shared.ts +16 -0
- package/src/notifications/adapters/slack.ts +6 -1
- package/src/notifications/adapters/telegram.ts +5 -8
- package/src/notifications/approval-card-data.ts +94 -1
- package/src/notifications/background-failure-signal.ts +116 -0
- package/src/notifications/broadcaster.ts +3 -9
- package/src/notifications/copy-composer.ts +41 -8
- package/src/notifications/decision-engine.ts +55 -0
- package/src/notifications/destination-resolver.ts +45 -5
- package/src/notifications/emit-signal.ts +19 -5
- package/src/notifications/guardian-question-mode.ts +57 -0
- package/src/notifications/types.ts +2 -8
- package/src/oauth/__tests__/seed-providers-managed.test.ts +18 -0
- package/src/oauth/connect-orchestrator.ts +16 -0
- package/src/oauth/seed-providers.ts +262 -0
- package/src/permissions/checker.test.ts +21 -0
- package/src/permissions/checker.ts +6 -0
- package/src/permissions/gateway-threshold-reader.test.ts +184 -0
- package/src/permissions/gateway-threshold-reader.ts +144 -10
- package/src/permissions/prompter.ts +0 -6
- package/src/permissions/types.ts +5 -4
- package/src/persistence/__tests__/bulk-write-gate.test.ts +0 -38
- package/src/persistence/bulk-write-gate.ts +9 -10
- package/src/persistence/conversation-crud.ts +88 -134
- package/src/persistence/conversation-title-service.ts +43 -29
- package/src/persistence/embeddings/embedding-local.ts +14 -85
- package/src/persistence/embeddings/embedding-runtime-manager.ts +1 -0
- package/src/persistence/lifecycle-events-store.test.ts +50 -0
- package/src/persistence/lifecycle-events-store.ts +75 -5
- package/src/platform/platform-patch-queue.test.ts +368 -0
- package/src/platform/platform-patch-queue.ts +190 -0
- package/src/platform/sync-avatar.test.ts +527 -0
- package/src/platform/sync-avatar.ts +209 -0
- package/src/platform/sync-identity.test.ts +75 -0
- package/src/platform/sync-identity.ts +17 -110
- package/src/plugin-api/model-profiles.test.ts +2 -2
- package/src/plugin-api/model-profiles.ts +7 -7
- package/src/plugin-api/transcription-session.ts +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +4 -0
- package/src/plugins/defaults/image-recovery/recover.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +133 -34
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +21 -31
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +13 -9
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +31 -4
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +0 -11
- package/src/plugins/defaults/memory/memory-retrospective-fork-boundary.ts +27 -13
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +183 -113
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +13 -13
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +2 -2
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +1 -1
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +4 -2
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +9 -42
- package/src/plugins/defaults/memory/v2/rerank-local.ts +1 -0
- package/src/plugins/defaults/memory/worker.ts +7 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +55 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +21 -3
- package/src/providers/connection-resolution.ts +2 -17
- package/src/providers/fallback-breaker.ts +389 -0
- package/src/providers/inference/__tests__/adapter-factory-opencode.test.ts +92 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +16 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +12 -0
- package/src/providers/inference/adapter-factory.ts +246 -3
- package/src/providers/inference/auth.ts +15 -14
- package/src/providers/inference/chatgpt-subscription-auth.ts +70 -0
- package/src/providers/inference/chatgpt-subscription-credentials.ts +84 -0
- package/src/providers/inference/resolve-auth.ts +1 -1
- package/src/providers/media-resolve.ts +2 -3
- package/src/providers/model-catalog.ts +100 -0
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +22 -0
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +198 -0
- package/src/providers/openai/api-error-normalization.ts +13 -0
- package/src/providers/openai/chat-completions-provider.ts +84 -0
- package/src/providers/opencode/client.test.ts +150 -0
- package/src/providers/opencode/client.ts +61 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/provider-resolvability.ts +20 -0
- package/src/providers/provider-secret-catalog.ts +3 -2
- package/src/providers/retry.ts +956 -68
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +42 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +136 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +120 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +316 -12
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +83 -3
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +132 -4
- package/src/providers/speech-to-text/provider-catalog.ts +191 -3
- package/src/providers/speech-to-text/resolve.ts +132 -24
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +296 -0
- package/src/providers/types.ts +39 -0
- package/src/providers/usage-tracking.ts +12 -1
- package/src/providers/vellum/client.ts +29 -0
- package/src/providers/vellum-model-routing.test.ts +2 -0
- package/src/providers/vellum-model-routing.ts +3 -3
- package/src/runtime/AGENTS.md +1 -2
- package/src/runtime/__tests__/agent-wake.test.ts +105 -3
- package/src/runtime/__tests__/background-job-runner.test.ts +89 -3
- package/src/runtime/agent-wake.ts +44 -5
- package/src/runtime/background-job-runner.ts +68 -50
- package/src/runtime/channel-readiness-service.ts +0 -39
- package/src/runtime/http-server.ts +12 -4
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +18 -18
- package/src/runtime/routes/__tests__/backup-routes.test.ts +9 -5
- package/src/runtime/routes/__tests__/chatgpt-subscription-auth-routes.test.ts +372 -0
- package/src/runtime/routes/__tests__/contact-routes.test.ts +7 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +96 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +37 -0
- package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +2 -1
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +87 -0
- package/src/runtime/routes/acp-claude-auth-routes.ts +25 -54
- package/src/runtime/routes/approval-routes.ts +0 -12
- package/src/runtime/routes/avatar-routes.ts +17 -30
- package/src/runtime/routes/backup-routes.ts +2 -2
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +296 -113
- package/src/runtime/routes/contact-prompt-routes.ts +65 -6
- package/src/runtime/routes/contact-routes.ts +20 -15
- package/src/runtime/routes/conversation-query-routes.ts +98 -10
- package/src/runtime/routes/conversation-routes.ts +2 -2
- package/src/runtime/routes/credential-routes.ts +2 -1
- package/src/runtime/routes/guardian-approval-interception.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +47 -48
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +18 -13
- package/src/runtime/routes/inbound-stages/admission-policy.ts +2 -2
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +20 -2
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +9 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +2 -2
- package/src/runtime/routes/inference-profiles-routes.ts +12 -7
- package/src/runtime/routes/inference-provider-connection-routes.ts +2 -2
- package/src/runtime/routes/inference-send-routes.ts +2 -2
- package/src/runtime/routes/ingress-status-routes.ts +2 -2
- package/src/runtime/routes/integrations/discord.ts +119 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +2 -2
- package/src/runtime/routes/mcp-auth-routes.ts +12 -6
- package/src/runtime/routes/migration-routes.ts +3 -1
- package/src/runtime/routes/oauth-pending-flows.ts +136 -0
- package/src/runtime/routes/secret-routes.ts +7 -0
- package/src/runtime/routes/stt-routes.ts +38 -6
- package/src/runtime/routes/wake-conversation-routes.ts +8 -1
- package/src/runtime/routes/watch-routes.ts +9 -5
- package/src/runtime/sync/resource-sync-events.ts +2 -0
- package/src/runtime/trust-verdict-consumer.ts +3 -3
- package/src/schedule/__tests__/worker-feature-flags.test.ts +58 -0
- package/src/schedule/retry-policy.ts +8 -8
- package/src/schedule/run-script.ts +14 -23
- package/src/schedule/schedule-recovery.ts +0 -1
- package/src/schedule/scheduler.ts +89 -51
- package/src/schedule/worker.ts +57 -0
- package/src/security/__tests__/openai-device-auth.test.ts +355 -0
- package/src/security/ces-rpc-record-backend.ts +123 -0
- package/src/security/oauth2.ts +7 -0
- package/src/security/openai-device-auth.ts +364 -0
- package/src/security/secure-keys.ts +15 -0
- package/src/skills/available-skills.ts +10 -1
- package/src/skills/catalog-install.ts +19 -1
- package/src/skills/inline-command-runner.ts +6 -2
- package/src/skills/platform-compatibility.test.ts +49 -0
- package/src/skills/platform-compatibility.ts +65 -0
- package/src/skills/tool-manifest.ts +20 -0
- package/src/stt/__tests__/roles.test.ts +152 -0
- package/src/stt/daemon-batch-transcriber.ts +4 -1
- package/src/stt/roles.ts +180 -0
- package/src/stt/stt-stream-session.ts +3 -2
- package/src/stt/types.ts +33 -3
- package/src/subagent/manager.ts +12 -0
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +34 -0
- package/src/telemetry/live-voice-funnel.ts +12 -2
- package/src/telemetry/telemetry-wire.generated.ts +6 -0
- package/src/telemetry/tool-audit.ts +83 -30
- package/src/telemetry/tool-executed-events-store.test.ts +0 -1
- package/src/telemetry/turn-outcome.ts +75 -4
- package/src/tools/client-os.ts +115 -0
- package/src/tools/computer-use/definitions.ts +11 -7
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -2
- package/src/tools/credentials/broker-types.ts +0 -71
- package/src/tools/credentials/broker.ts +6 -201
- package/src/tools/credentials/metadata-store.ts +65 -16
- package/src/tools/credentials/store.ts +2 -0
- package/src/tools/executor.ts +2 -8
- package/src/tools/host-shell.test.ts +75 -0
- package/src/tools/host-shell.ts +24 -0
- package/src/tools/host-terminal/host-shell.ts +15 -44
- package/src/tools/mcp/mcp-tool-factory.ts +44 -9
- package/src/tools/permission-checker.ts +73 -21
- package/src/tools/policy-context.ts +1 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/find-similar-skills.ts +10 -2
- package/src/tools/skills/load.ts +41 -6
- package/src/tools/skills/sandbox-runner.ts +8 -16
- package/src/tools/skills/skill-tool-factory.ts +1 -0
- package/src/tools/terminal/__tests__/safe-env.test.ts +64 -1
- package/src/tools/terminal/safe-env.ts +39 -9
- package/src/tools/terminal/shell.ts +12 -31
- package/src/tools/tool-approval-handler.ts +64 -10
- package/src/tools/tool-types.ts +10 -0
- package/src/tools/types.ts +19 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +4 -3
- package/src/tools/workflows/manage-workflows.ts +2 -2
- package/src/tools/workflows/run-workflow.test.ts +2 -1
- package/src/util/__tests__/file-use.test.ts +61 -0
- package/src/util/__tests__/process-table.test.ts +66 -0
- package/src/util/__tests__/process-tree.test.ts +46 -0
- package/src/util/errors.ts +1 -0
- package/src/util/file-use.ts +91 -0
- package/src/util/host-process.test.ts +17 -0
- package/src/util/host-process.ts +75 -0
- package/src/util/image-conversion.ts +39 -7
- package/src/util/platform.ts +32 -13
- package/src/util/process-table.ts +249 -0
- package/src/util/process-tree.ts +85 -129
- package/src/util/provider-error-patterns.ts +20 -0
- package/src/util/spawn.ts +9 -2
- package/src/watch/__tests__/watch-retro.test.ts +48 -1
- package/src/watch/watch-retro.ts +46 -4
- package/src/workspace/git-service.ts +4 -14
- package/src/workspace/migrations/147-rename-colliding-backup-profile-names.ts +360 -0
- package/src/workspace/migrations/148-strip-unsupported-fallback-profiles.ts +117 -0
- package/src/workspace/migrations/149-repoint-backup-profile-selections.ts +204 -0
- package/src/workspace/migrations/150-stt-flux-provider-to-model-family.ts +139 -0
- package/src/workspace/migrations/__tests__/150-stt-flux-provider-to-model-family.test.ts +160 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/permission-types.test.ts +0 -17
- package/src/channels/gateway-discord-admission.ts +0 -32
- package/src/persistence/fork-message-copy.ts +0 -239
- package/src/plugins/defaults/memory/__tests__/fork-message-copy.test.ts +0 -221
- package/src/security/__tests__/oauth2-device-code.test.ts +0 -431
- package/src/security/oauth2-device-code.ts +0 -312
|
@@ -2,28 +2,50 @@ import type {
|
|
|
2
2
|
ToolContext,
|
|
3
3
|
ToolExecutionResult,
|
|
4
4
|
} from "../../../../tools/types.js";
|
|
5
|
+
import { isWindows } from "../../../../util/platform.js";
|
|
5
6
|
|
|
6
7
|
const PANES = {
|
|
7
8
|
microphone: {
|
|
8
|
-
url: "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone",
|
|
9
9
|
label: "Microphone privacy",
|
|
10
|
-
|
|
10
|
+
urls: {
|
|
11
|
+
macos:
|
|
12
|
+
"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone",
|
|
13
|
+
windows: "ms-settings:privacy-microphone",
|
|
14
|
+
},
|
|
11
15
|
},
|
|
12
16
|
speech_recognition: {
|
|
13
|
-
url: "x-apple.systempreferences:com.apple.preference.security?Privacy_SpeechRecognition",
|
|
14
17
|
label: "Speech Recognition privacy",
|
|
15
|
-
|
|
18
|
+
urls: {
|
|
19
|
+
macos:
|
|
20
|
+
"x-apple.systempreferences:com.apple.preference.security?Privacy_SpeechRecognition",
|
|
21
|
+
windows: "ms-settings:privacy-speech",
|
|
22
|
+
},
|
|
16
23
|
},
|
|
17
24
|
} as const;
|
|
18
25
|
|
|
19
26
|
type PaneName = keyof typeof PANES;
|
|
27
|
+
type SettingsPlatform = keyof (typeof PANES)[PaneName]["urls"];
|
|
20
28
|
|
|
29
|
+
const VALID_PLATFORMS: SettingsPlatform[] = ["macos", "windows"];
|
|
21
30
|
const VALID_PANES = Object.keys(PANES) as PaneName[];
|
|
22
31
|
|
|
23
32
|
export async function run(
|
|
24
33
|
input: Record<string, unknown>,
|
|
25
34
|
context: ToolContext,
|
|
26
35
|
): Promise<ToolExecutionResult> {
|
|
36
|
+
const requestedPlatform = input.platform as string | undefined;
|
|
37
|
+
if (
|
|
38
|
+
requestedPlatform !== undefined &&
|
|
39
|
+
!VALID_PLATFORMS.includes(requestedPlatform as SettingsPlatform)
|
|
40
|
+
) {
|
|
41
|
+
return {
|
|
42
|
+
content: `Error: unknown platform "${requestedPlatform}". Valid platforms: ${VALID_PLATFORMS.join(
|
|
43
|
+
", ",
|
|
44
|
+
)}`,
|
|
45
|
+
isError: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
27
49
|
const pane = input.pane as string;
|
|
28
50
|
if (!VALID_PANES.includes(pane as PaneName)) {
|
|
29
51
|
return {
|
|
@@ -34,20 +56,23 @@ export async function run(
|
|
|
34
56
|
};
|
|
35
57
|
}
|
|
36
58
|
|
|
59
|
+
const platform =
|
|
60
|
+
(requestedPlatform as SettingsPlatform | undefined) ??
|
|
61
|
+
(isWindows() ? "windows" : "macos");
|
|
37
62
|
const meta = PANES[pane as PaneName];
|
|
38
63
|
|
|
39
|
-
// Send open_url to the client - the x-apple.systempreferences: scheme
|
|
40
|
-
// opens System Settings directly without a browser confirmation dialog.
|
|
41
64
|
if (context.sendToClient) {
|
|
42
65
|
context.sendToClient({
|
|
43
66
|
type: "open_url",
|
|
44
|
-
url: meta.
|
|
67
|
+
url: meta.urls[platform],
|
|
45
68
|
conversationId: context.conversationId,
|
|
46
69
|
});
|
|
47
70
|
}
|
|
48
71
|
|
|
72
|
+
const settingsName =
|
|
73
|
+
platform === "windows" ? "Windows Settings" : "System Settings";
|
|
49
74
|
return {
|
|
50
|
-
content: `Opened
|
|
75
|
+
content: `Opened ${settingsName} to ${meta.label}. Please enable Vellum Assistant.`,
|
|
51
76
|
isError: false,
|
|
52
77
|
};
|
|
53
78
|
}
|
|
@@ -4,6 +4,11 @@ import {
|
|
|
4
4
|
DEEPGRAM_MULTI_LANGUAGE_CODES,
|
|
5
5
|
DEEPGRAM_NOVA3_MONOLINGUAL_CODES,
|
|
6
6
|
} from "../../../../providers/speech-to-text/deepgram.js";
|
|
7
|
+
import {
|
|
8
|
+
isManagedSttProvider,
|
|
9
|
+
listProviderModelFamilies,
|
|
10
|
+
} from "../../../../providers/speech-to-text/provider-catalog.js";
|
|
11
|
+
import type { SttProviderId } from "../../../../stt/types.js";
|
|
7
12
|
import type {
|
|
8
13
|
ToolContext,
|
|
9
14
|
ToolExecutionResult,
|
|
@@ -47,6 +52,7 @@ const VOICE_SETTINGS = {
|
|
|
47
52
|
},
|
|
48
53
|
stt_provider: { type: "string" },
|
|
49
54
|
stt_language: { type: "string" },
|
|
55
|
+
stt_model: { type: "string" },
|
|
50
56
|
} satisfies Record<string, VoiceSettingMeta>;
|
|
51
57
|
|
|
52
58
|
type VoiceSettingName = keyof typeof VOICE_SETTINGS;
|
|
@@ -64,6 +70,7 @@ const FRIENDLY_NAMES: Record<VoiceSettingName, string> = {
|
|
|
64
70
|
fish_audio_reference_id: "Fish Audio voice",
|
|
65
71
|
stt_provider: "Speech-to-text provider",
|
|
66
72
|
stt_language: "Speech-to-text language",
|
|
73
|
+
stt_model: "Speech-to-text model family",
|
|
67
74
|
};
|
|
68
75
|
|
|
69
76
|
/**
|
|
@@ -293,6 +300,25 @@ function validateSetting(
|
|
|
293
300
|
}
|
|
294
301
|
return { ok: true, coerced: value.trim() };
|
|
295
302
|
}
|
|
303
|
+
case "stt_model": {
|
|
304
|
+
const families = listProviderModelFamilies(
|
|
305
|
+
(activeSttProviderId ?? "") as SttProviderId,
|
|
306
|
+
);
|
|
307
|
+
if (families.length === 0) {
|
|
308
|
+
return {
|
|
309
|
+
ok: false,
|
|
310
|
+
error: `the active speech-to-text provider${activeSttProviderId ? ` (${activeSttProviderId})` : ""} offers a single model, so stt_model cannot be set`,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
const normalized = typeof value === "string" ? value.trim() : "";
|
|
314
|
+
if (!families.includes(normalized as never)) {
|
|
315
|
+
return {
|
|
316
|
+
ok: false,
|
|
317
|
+
error: `stt_model must be one of: ${families.join(", ")}`,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
return { ok: true, coerced: normalized };
|
|
321
|
+
}
|
|
296
322
|
case "stt_language": {
|
|
297
323
|
if (typeof value !== "string") {
|
|
298
324
|
return {
|
|
@@ -410,7 +436,9 @@ export async function run(
|
|
|
410
436
|
// same source the sparse-config write-seeding below reads): the extended
|
|
411
437
|
// roster and "multi" are only valid where nova-3 runs.
|
|
412
438
|
const activeSttProviderId =
|
|
413
|
-
setting === "stt_language"
|
|
439
|
+
setting === "stt_language" || setting === "stt_model"
|
|
440
|
+
? getConfig().services.stt.provider
|
|
441
|
+
: undefined;
|
|
414
442
|
|
|
415
443
|
const validation = validateSetting(
|
|
416
444
|
setting,
|
|
@@ -422,9 +450,14 @@ export async function run(
|
|
|
422
450
|
return { content: `Error: ${validation.error}`, isError: true };
|
|
423
451
|
}
|
|
424
452
|
|
|
453
|
+
// Managed speech has more than one STT id, so the gate reads the catalog
|
|
454
|
+
// rather than a literal: without this, setting a managed provider other
|
|
455
|
+
// than "vellum" on a disconnected assistant persists happily and then
|
|
456
|
+
// resolves no transcriber at all.
|
|
425
457
|
const wantsManagedSpeech =
|
|
426
|
-
(setting === "stt_provider"
|
|
427
|
-
|
|
458
|
+
(setting === "stt_provider" &&
|
|
459
|
+
isManagedSttProvider(validation.coerced as SttProviderId)) ||
|
|
460
|
+
(setting === "tts_provider" && validation.coerced === "vellum");
|
|
428
461
|
if (wantsManagedSpeech && !(await managedSpeechAvailable())) {
|
|
429
462
|
return {
|
|
430
463
|
content:
|
|
@@ -504,6 +537,24 @@ export async function run(
|
|
|
504
537
|
invalidateConfigCache();
|
|
505
538
|
}
|
|
506
539
|
|
|
540
|
+
if (setting === "stt_model") {
|
|
541
|
+
// Scoped to the provider that is active now, which validation already
|
|
542
|
+
// checked can serve the family. The provider is seeded for the same
|
|
543
|
+
// reason stt_language seeds it: a sparse block missing `provider` fails
|
|
544
|
+
// SttServiceSchema and trips the loader's salvage ladder.
|
|
545
|
+
const provider = getConfig().services.stt.provider;
|
|
546
|
+
if (!rawSttProviderPresent(raw)) {
|
|
547
|
+
setNestedValue(raw, "services.stt.provider", provider);
|
|
548
|
+
}
|
|
549
|
+
setNestedValue(
|
|
550
|
+
raw,
|
|
551
|
+
`services.stt.providers.${provider}.model`,
|
|
552
|
+
validation.coerced,
|
|
553
|
+
);
|
|
554
|
+
saveRawConfig(raw);
|
|
555
|
+
invalidateConfigCache();
|
|
556
|
+
}
|
|
557
|
+
|
|
507
558
|
// Provider scoping happened in validation (xai only accepts its verified
|
|
508
559
|
// set); for the remaining providers the write is unconditional. Auto-detect
|
|
509
560
|
// providers ignore the value at resolve time, so writing it is harmless and
|
|
@@ -239,7 +239,7 @@ export async function run(
|
|
|
239
239
|
// the model verbatim rather than as the "nothing configured" copy below.
|
|
240
240
|
let transcriber: BatchTranscriber | null;
|
|
241
241
|
try {
|
|
242
|
-
transcriber = await resolveBatchTranscriber();
|
|
242
|
+
transcriber = await resolveBatchTranscriber({ role: "batch" });
|
|
243
243
|
} catch (err) {
|
|
244
244
|
return { content: (err as Error).message, isError: true };
|
|
245
245
|
}
|
|
@@ -9,15 +9,21 @@ import type { ModelIntent } from "../providers/types.js";
|
|
|
9
9
|
import { getManagedUpstream } from "../providers/vellum-model-routing.js";
|
|
10
10
|
import { getBalancedModelExperimentArm } from "./balanced-model-experiment.js";
|
|
11
11
|
import {
|
|
12
|
+
BACKUP_PROFILE_KEYS,
|
|
13
|
+
type BackupProfileKey,
|
|
12
14
|
DEFAULT_PROFILE_KEYS,
|
|
13
15
|
DEFAULT_PROFILE_PROVIDERS,
|
|
14
16
|
type DefaultProfileKey,
|
|
15
17
|
type DefaultProfileProvider,
|
|
18
|
+
FALLBACK_PROFILE_BY_KEY,
|
|
19
|
+
isBackupProfileKey,
|
|
20
|
+
isDefaultProfileKey,
|
|
16
21
|
isDefaultProfileProvider,
|
|
17
22
|
OS_BETA_PROFILE_KEY,
|
|
18
23
|
} from "./default-profile-names.js";
|
|
19
24
|
import { resolveDefaultConnectionName } from "./default-provider-resolution.js";
|
|
20
25
|
import {
|
|
26
|
+
backupProfilesResolveUnderDefaultProvider,
|
|
21
27
|
DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
22
28
|
DEFAULT_PROVIDER_CHOICES,
|
|
23
29
|
type DefaultProviderConfig,
|
|
@@ -70,6 +76,13 @@ type ProfileImpls = Record<DefaultProfileKey, DefaultProfileTemplate>;
|
|
|
70
76
|
* concrete dispatch providers, and the model is what selects the upstream.
|
|
71
77
|
* Overwritten in workspace config on every daemon boot so Vellum can push
|
|
72
78
|
* model/config updates to customers in new releases.
|
|
79
|
+
*
|
|
80
|
+
* Each implementation points at its managed backup profile via
|
|
81
|
+
* `fallbackProfile` (`BACKUP_PROFILE_IMPLS` below): a backup pins a model at
|
|
82
|
+
* a different upstream provider, so an outage-type failure at the primary's
|
|
83
|
+
* provider can be served by re-sending on the backup. Vellum column only:
|
|
84
|
+
* the BYOK and chatgpt columns carry no pointers, since those installs may
|
|
85
|
+
* hold no credential for the backup's provider.
|
|
73
86
|
*/
|
|
74
87
|
const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
75
88
|
balanced: {
|
|
@@ -78,6 +91,7 @@ const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
|
78
91
|
source: "managed",
|
|
79
92
|
label: "Balanced",
|
|
80
93
|
description: "Good balance of quality, cost, and speed",
|
|
94
|
+
fallbackProfile: FALLBACK_PROFILE_BY_KEY.balanced,
|
|
81
95
|
maxTokens: 32000,
|
|
82
96
|
effort: "high",
|
|
83
97
|
thinking: { enabled: true, streamThinking: true },
|
|
@@ -91,6 +105,7 @@ const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
|
91
105
|
source: "managed",
|
|
92
106
|
label: "Quality",
|
|
93
107
|
description: "High-quality results with the most capable model",
|
|
108
|
+
fallbackProfile: FALLBACK_PROFILE_BY_KEY["quality-optimized"],
|
|
94
109
|
maxTokens: 32000,
|
|
95
110
|
effort: "high",
|
|
96
111
|
thinking: { enabled: true, streamThinking: true },
|
|
@@ -107,6 +122,7 @@ const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
|
107
122
|
// surface the live model beside the description, so a model name in
|
|
108
123
|
// this copy would go stale the moment the pin moves.
|
|
109
124
|
description: "Cheapest responses, for high-volume work",
|
|
125
|
+
fallbackProfile: FALLBACK_PROFILE_BY_KEY["cost-optimized"],
|
|
110
126
|
maxTokens: 8192,
|
|
111
127
|
// Explicit reasoning opt-out. OpenAI-compat APIs default reasoning to
|
|
112
128
|
// "medium" when the field is omitted, and effort-driven providers encode
|
|
@@ -136,6 +152,7 @@ const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
|
136
152
|
source: "managed",
|
|
137
153
|
label: "Speed",
|
|
138
154
|
description: "Fastest responses, with reasoning turned off",
|
|
155
|
+
fallbackProfile: FALLBACK_PROFILE_BY_KEY["latency-optimized"],
|
|
139
156
|
maxTokens: 8192,
|
|
140
157
|
// Explicit reasoning opt-out, matching `cost-optimized` above: this
|
|
141
158
|
// profile advertises reasoning as off, and OpenAI-compat APIs default
|
|
@@ -149,6 +166,80 @@ const VELLUM_PROFILE_IMPLS: ProfileImpls = {
|
|
|
149
166
|
},
|
|
150
167
|
};
|
|
151
168
|
|
|
169
|
+
/**
|
|
170
|
+
* The managed backup profiles, one per default profile: the route a primary's
|
|
171
|
+
* `fallbackProfile` pointer names. Vellum column only: backups never
|
|
172
|
+
* materialize for BYOK or chatgpt installs. Like the primaries, models are
|
|
173
|
+
* pinned (never intents) and stamped `provider: "vellum"`, so dispatch
|
|
174
|
+
* derives the upstream from the model. Every backup pins its model at a
|
|
175
|
+
* DIFFERENT upstream provider than its primary (that cross-provider split is
|
|
176
|
+
* the entire point), and the module-load validation below enforces
|
|
177
|
+
* routability.
|
|
178
|
+
*
|
|
179
|
+
* Descriptions name the tier they back, never the concrete model: clients
|
|
180
|
+
* surface the live model beside the description, so a model name in this
|
|
181
|
+
* copy would go stale the moment a pin moves.
|
|
182
|
+
*/
|
|
183
|
+
const BACKUP_PROFILE_IMPLS: Record<BackupProfileKey, DefaultProfileTemplate> = {
|
|
184
|
+
"balanced-backup": {
|
|
185
|
+
model: "claude-sonnet-5",
|
|
186
|
+
provider: "vellum",
|
|
187
|
+
source: "managed",
|
|
188
|
+
label: "Balanced Backup",
|
|
189
|
+
description: "Automatic backup for the Balanced profile",
|
|
190
|
+
maxTokens: 32000,
|
|
191
|
+
effort: "high",
|
|
192
|
+
thinking: { enabled: true, streamThinking: true },
|
|
193
|
+
contextWindow: {
|
|
194
|
+
maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
"quality-optimized-backup": {
|
|
198
|
+
model: "claude-opus-5",
|
|
199
|
+
provider: "vellum",
|
|
200
|
+
source: "managed",
|
|
201
|
+
label: "Quality Backup",
|
|
202
|
+
description: "Automatic backup for the Quality profile",
|
|
203
|
+
maxTokens: 32000,
|
|
204
|
+
effort: "high",
|
|
205
|
+
thinking: { enabled: true, streamThinking: true },
|
|
206
|
+
contextWindow: {
|
|
207
|
+
maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
"cost-optimized-backup": {
|
|
211
|
+
model: "gemini-3.1-flash-lite",
|
|
212
|
+
provider: "vellum",
|
|
213
|
+
source: "managed",
|
|
214
|
+
label: "Cost Backup",
|
|
215
|
+
description: "Automatic backup for the Cost profile",
|
|
216
|
+
maxTokens: 8192,
|
|
217
|
+
// Explicit reasoning opt-out, matching the primary Cost profile: OpenAI-
|
|
218
|
+
// compat APIs default reasoning to "medium" when the field is omitted,
|
|
219
|
+
// and effort-driven providers encode disabled thinking through this same
|
|
220
|
+
// knob (see DISABLED_THINKING_USES_EFFORT_PROVIDERS in
|
|
221
|
+
// providers/retry.ts).
|
|
222
|
+
effort: "none",
|
|
223
|
+
thinking: { enabled: false, streamThinking: false },
|
|
224
|
+
contextWindow: {
|
|
225
|
+
maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
"latency-optimized-backup": {
|
|
229
|
+
model: "claude-haiku-4-5-20251001",
|
|
230
|
+
provider: "vellum",
|
|
231
|
+
source: "managed",
|
|
232
|
+
label: "Speed Backup",
|
|
233
|
+
description: "Automatic backup for the Speed profile",
|
|
234
|
+
maxTokens: 8192,
|
|
235
|
+
effort: "low",
|
|
236
|
+
thinking: { enabled: false, streamThinking: false },
|
|
237
|
+
contextWindow: {
|
|
238
|
+
maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
|
|
152
243
|
/**
|
|
153
244
|
* Arm to managed model pin for the `experiment-balanced-model-2026-08-06` A/B
|
|
154
245
|
* test (`balanced-model-experiment.ts` owns the flag read). An arm repoints
|
|
@@ -335,14 +426,18 @@ export const PROFILE_IMPLS: Record<
|
|
|
335
426
|
>;
|
|
336
427
|
|
|
337
428
|
/**
|
|
338
|
-
* Managed profiles, i.e. the `vellum` column keyed by profile name
|
|
339
|
-
*
|
|
340
|
-
*
|
|
429
|
+
* Managed profiles, i.e. the `vellum` column keyed by profile name, plus the
|
|
430
|
+
* managed backup profiles. Backups come after the primaries, which is what
|
|
431
|
+
* places them after the primaries in the seeded `profileOrder`: the seeder
|
|
432
|
+
* inserts missing managed keys in this record's order. Keyed by the
|
|
433
|
+
* user-facing defaults only: an internal profile is code-resolved and never
|
|
434
|
+
* listed or ordered.
|
|
341
435
|
*/
|
|
342
436
|
export const MANAGED_PROFILE_TEMPLATES: Record<string, DefaultProfileTemplate> =
|
|
343
|
-
Object.fromEntries(
|
|
344
|
-
DEFAULT_PROFILE_KEYS.map((key) => [key, PROFILE_IMPLS[key].vellum]),
|
|
345
|
-
|
|
437
|
+
Object.fromEntries([
|
|
438
|
+
...DEFAULT_PROFILE_KEYS.map((key) => [key, PROFILE_IMPLS[key].vellum]),
|
|
439
|
+
...BACKUP_PROFILE_KEYS.map((key) => [key, BACKUP_PROFILE_IMPLS[key]]),
|
|
440
|
+
]);
|
|
346
441
|
|
|
347
442
|
/**
|
|
348
443
|
* The values BYOK hatch seeding wrote onto each `custom-*` copy, for the keys
|
|
@@ -413,8 +508,23 @@ export const OS_BETA_PROFILE_TEMPLATE: DefaultProfileTemplate = {
|
|
|
413
508
|
* audible dead air rather than a slow reply. A same-named
|
|
414
509
|
* workspace entry stays on disk and stays listed; it just never governs what
|
|
415
510
|
* this name resolves to.
|
|
511
|
+
*
|
|
512
|
+
* All four backups carry the same protection rather than only
|
|
513
|
+
* `latency-optimized-backup`. The narrow argument covers that one alone: it
|
|
514
|
+
* serves the live-voice path whenever the primary falls back, so a shadow
|
|
515
|
+
* reintroduces exactly the dead-air risk the primary's protection exists to
|
|
516
|
+
* prevent. The broader argument covers all four, and is why the whole set is
|
|
517
|
+
* here: a backup only earns its place by pinning a model at a different
|
|
518
|
+
* upstream than the primary it backs (see `BACKUP_PROFILE_IMPLS`), and a
|
|
519
|
+
* user-owned shadow can silently repoint it at the primary's own provider,
|
|
520
|
+
* so the fallback re-sends into the outage it exists to route around. A
|
|
521
|
+
* backup also has no per-provider matrix column, so there is nothing a
|
|
522
|
+
* workspace overlay could legitimately own on it.
|
|
416
523
|
*/
|
|
417
|
-
export const CODE_OWNED_PROFILE_NAMES = new Set<string>([
|
|
524
|
+
export const CODE_OWNED_PROFILE_NAMES = new Set<string>([
|
|
525
|
+
"latency-optimized",
|
|
526
|
+
...BACKUP_PROFILE_KEYS,
|
|
527
|
+
]);
|
|
418
528
|
|
|
419
529
|
// All managed profiles, including the flag-gated os-beta, are invariant:
|
|
420
530
|
// their MANAGED-SOURCE entries are read-only to user-facing writes except
|
|
@@ -423,6 +533,7 @@ export const CODE_OWNED_PROFILE_NAMES = new Set<string>(["latency-optimized"]);
|
|
|
423
533
|
// the on-disk entry's `source` being `managed`.
|
|
424
534
|
export const INVARIANT_PROFILE_NAMES = new Set<string>([
|
|
425
535
|
...DEFAULT_PROFILE_KEYS,
|
|
536
|
+
...BACKUP_PROFILE_KEYS,
|
|
426
537
|
OS_BETA_PROFILE_KEY,
|
|
427
538
|
]);
|
|
428
539
|
|
|
@@ -435,6 +546,7 @@ export const INVARIANT_PROFILE_NAMES = new Set<string>([
|
|
|
435
546
|
// same-named user profile.
|
|
436
547
|
export const MANAGED_PROFILE_NAMES = new Set<string>([
|
|
437
548
|
...DEFAULT_PROFILE_KEYS,
|
|
549
|
+
...BACKUP_PROFILE_KEYS,
|
|
438
550
|
OS_BETA_PROFILE_KEY,
|
|
439
551
|
]);
|
|
440
552
|
|
|
@@ -502,6 +614,22 @@ for (const key of DEFAULT_PROFILE_KEYS) {
|
|
|
502
614
|
}
|
|
503
615
|
}
|
|
504
616
|
|
|
617
|
+
// Backup profiles get the same eager verification as the vellum column: a
|
|
618
|
+
// pinned model that no managed upstream serves would make the fallback route
|
|
619
|
+
// undispatchable exactly when it is needed. The cross-provider rule (backup
|
|
620
|
+
// upstream differs from the primary's) is asserted in
|
|
621
|
+
// __tests__/default-profile-catalog-fallback.test.ts, arm pins included.
|
|
622
|
+
for (const key of BACKUP_PROFILE_KEYS) {
|
|
623
|
+
const impl = BACKUP_PROFILE_IMPLS[key];
|
|
624
|
+
if (impl.model == null || getManagedUpstream(impl.model) === null) {
|
|
625
|
+
throw new Error(
|
|
626
|
+
`BACKUP_PROFILE_IMPLS[${key}] references model "${impl.model ?? ""}" ` +
|
|
627
|
+
`which is not served by any managed upstream. ` +
|
|
628
|
+
`Update model-catalog.ts or default-profile-catalog.ts.`,
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
505
633
|
// The experiment arms substitute into the managed column at request time, so
|
|
506
634
|
// they need the same routability guarantee as the pins validated above: a
|
|
507
635
|
// LaunchDarkly arm must never select a model no managed upstream serves.
|
|
@@ -542,6 +670,10 @@ function buildDefaultProfileEntries(): Record<string, ProfileEntry> {
|
|
|
542
670
|
const impl = PROFILE_IMPLS[key].vellum;
|
|
543
671
|
entries[key] = materializeProfile(impl, impl.provider);
|
|
544
672
|
}
|
|
673
|
+
for (const key of BACKUP_PROFILE_KEYS) {
|
|
674
|
+
const impl = BACKUP_PROFILE_IMPLS[key];
|
|
675
|
+
entries[key] = materializeProfile(impl, impl.provider);
|
|
676
|
+
}
|
|
545
677
|
entries[OS_BETA_PROFILE_KEY] = materializeProfile(
|
|
546
678
|
OS_BETA_PROFILE_TEMPLATE,
|
|
547
679
|
OS_BETA_PROFILE_TEMPLATE.provider,
|
|
@@ -617,6 +749,16 @@ function resolveAgainstBody(
|
|
|
617
749
|
body: ProfileEntry | undefined,
|
|
618
750
|
): ProfileEntry | undefined {
|
|
619
751
|
if (body == null) {
|
|
752
|
+
// A managed stub is the workspace's slot for a code-owned profile, never
|
|
753
|
+
// a profile of its own, so with no body behind it there is nothing to
|
|
754
|
+
// resolve. Only a backup name reaches this branch with a stub (the
|
|
755
|
+
// default keys always have a body), and it reaches it on the columns
|
|
756
|
+
// where the backups do not exist. Resolving to the stub would list a
|
|
757
|
+
// profile with no provider or model and let a reference to it look
|
|
758
|
+
// valid, which is precisely what `LLMSchema` rejects on those columns.
|
|
759
|
+
if (isBackupProfileKey(name) && workspace?.source === "managed") {
|
|
760
|
+
return undefined;
|
|
761
|
+
}
|
|
620
762
|
return workspace;
|
|
621
763
|
}
|
|
622
764
|
if (CODE_OWNED_PROFILE_NAMES.has(name)) {
|
|
@@ -670,9 +812,7 @@ export function resolveDefaultProfileForProvider(
|
|
|
670
812
|
);
|
|
671
813
|
}
|
|
672
814
|
|
|
673
|
-
export
|
|
674
|
-
return (DEFAULT_PROFILE_KEYS as readonly string[]).includes(name);
|
|
675
|
-
}
|
|
815
|
+
export { isDefaultProfileKey } from "./default-profile-names.js";
|
|
676
816
|
|
|
677
817
|
/**
|
|
678
818
|
* The implementation of default profile `key` on `provider`: the named matrix
|
|
@@ -706,6 +846,18 @@ function defaultProfileBodyForProvider(
|
|
|
706
846
|
defaultProvider: DefaultProviderConfig | null,
|
|
707
847
|
): ProfileEntry | undefined {
|
|
708
848
|
if (!isDefaultProfileKey(name)) {
|
|
849
|
+
// Backup profiles are companions of the managed (`vellum`) column only:
|
|
850
|
+
// under a BYOK or chatgpt default provider the primaries carry no
|
|
851
|
+
// `fallbackProfile` pointers, and the backups must not materialize
|
|
852
|
+
// either, since the install may hold no credential for the backup's
|
|
853
|
+
// provider. A null defaultProvider predates `llm.defaultProvider` and
|
|
854
|
+
// resolves to the managed column, so it keeps its backups.
|
|
855
|
+
if (
|
|
856
|
+
isBackupProfileKey(name) &&
|
|
857
|
+
!backupProfilesResolveUnderDefaultProvider(defaultProvider)
|
|
858
|
+
) {
|
|
859
|
+
return undefined;
|
|
860
|
+
}
|
|
709
861
|
return CODE_DEFAULT_PROFILE_ENTRIES[name];
|
|
710
862
|
}
|
|
711
863
|
if (defaultProvider == null) {
|
|
@@ -752,6 +904,14 @@ function clampMaxTokensToModelCap(body: ProfileEntry): ProfileEntry {
|
|
|
752
904
|
* available code default, merged per `getEffectiveProfile`. This is the
|
|
753
905
|
* record all runtime readers of `llm.profiles` should consume; the raw
|
|
754
906
|
* workspace record is a write-path concern.
|
|
907
|
+
*
|
|
908
|
+
* Deliberately provider-agnostic: it lists the managed backups whatever
|
|
909
|
+
* `llm.defaultProvider` says, because it resolves names against the passed
|
|
910
|
+
* catalog alone and never reads config. Internal resolution and reference
|
|
911
|
+
* validation use `getEffectiveProfilesForProvider`; user-facing selectors use
|
|
912
|
+
* `getUserSelectableProfilesForProvider`, which additionally removes backups
|
|
913
|
+
* from the managed column. Keeping those views separate lets automatic
|
|
914
|
+
* fallback resolve an internal route without offering it as a direct choice.
|
|
755
915
|
*/
|
|
756
916
|
export function getEffectiveProfiles(
|
|
757
917
|
workspaceProfiles: Record<string, ProfileEntry> | undefined,
|
|
@@ -794,7 +954,32 @@ export function getEffectiveProfilesForProvider(
|
|
|
794
954
|
);
|
|
795
955
|
if (entry != null) {
|
|
796
956
|
effective[name] = entry;
|
|
957
|
+
continue;
|
|
797
958
|
}
|
|
959
|
+
// Nothing resolved, so the name must not survive from the workspace
|
|
960
|
+
// spread above: a backup carrying only a managed stub on a column that
|
|
961
|
+
// has no backups would otherwise be listed as an available profile with
|
|
962
|
+
// no provider or model behind it.
|
|
963
|
+
delete effective[name];
|
|
798
964
|
}
|
|
799
965
|
return effective;
|
|
800
966
|
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* The effective profile view used by user-facing selectors. Managed backups
|
|
970
|
+
* remain in the full effective catalog for automatic fallback resolution, but
|
|
971
|
+
* are internal routes rather than profiles a user can choose directly.
|
|
972
|
+
*/
|
|
973
|
+
export function getUserSelectableProfilesForProvider(
|
|
974
|
+
workspaceProfiles: Record<string, ProfileEntry> | undefined,
|
|
975
|
+
defaultProvider: DefaultProviderConfig | null,
|
|
976
|
+
): Record<string, ProfileEntry> {
|
|
977
|
+
const selectable = getEffectiveProfilesForProvider(
|
|
978
|
+
workspaceProfiles,
|
|
979
|
+
defaultProvider,
|
|
980
|
+
);
|
|
981
|
+
for (const name of BACKUP_PROFILE_KEYS) {
|
|
982
|
+
delete selectable[name];
|
|
983
|
+
}
|
|
984
|
+
return selectable;
|
|
985
|
+
}
|
|
@@ -26,6 +26,47 @@ export const DEFAULT_PROFILE_KEYS = [
|
|
|
26
26
|
] as const;
|
|
27
27
|
export type DefaultProfileKey = (typeof DEFAULT_PROFILE_KEYS)[number];
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Stable keys of the managed backup profiles, one per default profile.
|
|
31
|
+
* Deliberately NOT part of `DEFAULT_PROFILE_KEYS`: that array drives picker
|
|
32
|
+
* order and the intent x provider matrix, while backups are companions of
|
|
33
|
+
* the managed (`vellum`) column only. Each backup pins a model at a
|
|
34
|
+
* different upstream provider than its primary, so an outage at the
|
|
35
|
+
* primary's provider can be served by re-sending on the backup (see the
|
|
36
|
+
* `fallbackProfile` field on `ProfileEntry`).
|
|
37
|
+
*/
|
|
38
|
+
export const BACKUP_PROFILE_KEYS = [
|
|
39
|
+
"balanced-backup",
|
|
40
|
+
"quality-optimized-backup",
|
|
41
|
+
"cost-optimized-backup",
|
|
42
|
+
"latency-optimized-backup",
|
|
43
|
+
] as const;
|
|
44
|
+
export type BackupProfileKey = (typeof BACKUP_PROFILE_KEYS)[number];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The backup profile each default profile falls back to. Applied to the
|
|
48
|
+
* managed (`vellum`) column implementations only: BYOK installs may hold no
|
|
49
|
+
* credential for the backup's provider, so their columns carry no
|
|
50
|
+
* `fallbackProfile` pointers.
|
|
51
|
+
*/
|
|
52
|
+
export const FALLBACK_PROFILE_BY_KEY: Record<
|
|
53
|
+
DefaultProfileKey,
|
|
54
|
+
BackupProfileKey
|
|
55
|
+
> = {
|
|
56
|
+
balanced: "balanced-backup",
|
|
57
|
+
"quality-optimized": "quality-optimized-backup",
|
|
58
|
+
"cost-optimized": "cost-optimized-backup",
|
|
59
|
+
"latency-optimized": "latency-optimized-backup",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export function isDefaultProfileKey(value: string): value is DefaultProfileKey {
|
|
63
|
+
return (DEFAULT_PROFILE_KEYS as readonly string[]).includes(value);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function isBackupProfileKey(value: string): value is BackupProfileKey {
|
|
67
|
+
return (BACKUP_PROFILE_KEYS as readonly string[]).includes(value);
|
|
68
|
+
}
|
|
69
|
+
|
|
29
70
|
/**
|
|
30
71
|
* Flag-gated default profile: only available while the `os-beta` feature
|
|
31
72
|
* flag has reconciled it into the workspace (see `sync-gated-profiles.ts`).
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
"scope": "assistant",
|
|
290
290
|
"key": "channel-trust-floors",
|
|
291
291
|
"label": "Channel Trust Floors",
|
|
292
|
-
"description": "
|
|
292
|
+
"description": "Server-side switch for admission-floor enforcement: the gateway kill switch, the runtime floor stage, and enforcement-time policy resolution gate on it. Configuration reads and writes stay available while it is off. On by default. Client UI visibility is version-gated, not flag-gated.",
|
|
293
293
|
"defaultEnabled": true
|
|
294
294
|
},
|
|
295
295
|
{
|
|
@@ -386,7 +386,39 @@
|
|
|
386
386
|
"scope": "client",
|
|
387
387
|
"key": "obscure-credits",
|
|
388
388
|
"label": "Obscure Credits",
|
|
389
|
-
"description": "
|
|
389
|
+
"description": "Obscures raw credit dollar amounts across the web billing surfaces in favor of a usage-relative view. The Plan section's current-plan tile trades its price footer for a Usage Balance bar and its credits spec chip reads \"<Package> usage, reset monthly\"; the plans takeover, custom-plan modal, and Pro provisioning takeover swap dollar credit wording for the catalog's usage labels; the Credits balance tile and the chat preferences menu show only credit bought or earned beyond the plan's included grants. Chat low-balance and daily-limit banners still name credits. Off leaves every surface exactly as it ships today.",
|
|
390
|
+
"defaultEnabled": false
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"id": "ios-avatar-app-icon",
|
|
394
|
+
"scope": "client",
|
|
395
|
+
"key": "ios-avatar-app-icon",
|
|
396
|
+
"label": "iOS Avatar App Icon",
|
|
397
|
+
"description": "Shows the App icon picker in Settings -> General, where any user chooses an eyes-on-color home screen icon for iOS, seeds the picker from their assistant's character avatar, or resets to the default. Every change is a press, and iOS confirms each one with an alert of its own. Off hides the picker and leaves the default icon in place.",
|
|
398
|
+
"defaultEnabled": false
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"id": "channel-conversation-sidecar",
|
|
402
|
+
"scope": "client",
|
|
403
|
+
"key": "channel-conversation-sidecar",
|
|
404
|
+
"label": "Channel Conversation Sidecar",
|
|
405
|
+
"description": "Renders a conversation bound to an external channel (Slack, Telegram, Discord, phone, email, and any other channel adapter) as two lanes in web chat: Vellum stays the primary full-width lane, and the canonical external-channel transcript moves into the existing read-only right drawer, opened from a channel-thread control in the chat header. Rows the client can attribute to the external channel are drawn once, in the drawer, instead of being blended into the Vellum lane. The drawer offers an Open in <channel> secondary action and a per-message Reference in Vellum action that stages one quoted reference above the Vellum composer. The Vellum composer stays the only input; nothing about delivery, routing, or permissions changes. Off leaves the header deep-link pill and the blended transcript unchanged.",
|
|
406
|
+
"defaultEnabled": false
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"id": "monday-oauth",
|
|
410
|
+
"scope": "assistant",
|
|
411
|
+
"key": "monday-oauth",
|
|
412
|
+
"label": "monday.com Integration",
|
|
413
|
+
"description": "Gates the seeded monday.com OAuth provider. When off, the provider is hidden from GET /v1/oauth/providers, its get-by-id route, and the connect/update routes, so it cannot be listed or connected from the CLI, gateway, or web integrations list. The row is still seeded into oauth_providers on startup; only its visibility changes.",
|
|
414
|
+
"defaultEnabled": false
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"id": "chatgpt-device-code-login",
|
|
418
|
+
"scope": "client",
|
|
419
|
+
"key": "chatgpt-device-code-login",
|
|
420
|
+
"label": "ChatGPT Device Code Login",
|
|
421
|
+
"description": "Gates the device-code sign-in as the primary ChatGPT subscription connect flow in the web client. Off: the redirect-and-paste flow is the only flow the connect section shows, with no device code UI and no other-sign-in-options disclosure. On: device code leads, and the redirect-and-paste flow stays reachable behind that disclosure and takes the section over when the assistant has no device-auth route.",
|
|
390
422
|
"defaultEnabled": false
|
|
391
423
|
}
|
|
392
424
|
]
|
|
@@ -1,16 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getUserSelectableProfilesForProvider } from "./default-profile-catalog.js";
|
|
2
2
|
import { getConfigReadOnly } from "./loader.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Validate an inference-profile key against the effective profile catalog
|
|
6
6
|
* (code-defined defaults + workspace `llm.profiles`). Returns a user-facing
|
|
7
7
|
* error message when the key is empty or unknown, or `null` when valid.
|
|
8
|
+
*
|
|
9
|
+
* Resolved through the `llm.defaultProvider`-aware user-selectable view so
|
|
10
|
+
* availability matches what a direct profile pin can choose. Managed backup
|
|
11
|
+
* routes remain available to automatic fallback resolution but are not
|
|
12
|
+
* reported as selectable profiles.
|
|
8
13
|
*/
|
|
9
14
|
export function validateInferenceProfileKey(profile: string): string | null {
|
|
10
15
|
if (!profile.trim()) {
|
|
11
16
|
return "inferenceProfile must be a non-empty string";
|
|
12
17
|
}
|
|
13
|
-
const
|
|
18
|
+
const llm = getConfigReadOnly().llm;
|
|
19
|
+
const profiles = getUserSelectableProfilesForProvider(
|
|
20
|
+
llm?.profiles,
|
|
21
|
+
llm?.defaultProvider ?? null,
|
|
22
|
+
);
|
|
14
23
|
const entry = profiles[profile];
|
|
15
24
|
if (entry === undefined) {
|
|
16
25
|
const available = Object.keys(profiles).sort();
|