import { ensureAuthProfileStore, resolveAuthProfileOrder } from "../agents/auth-profiles.js"; import { resolveEnvApiKey } from "../agents/model-auth.js"; import { formatApiKeyPreview, normalizeApiKeyInput, validateApiKeyInput, } from "./auth-choice.api-key.js"; import { applyAuthChoiceHuggingface } from "./auth-choice.apply.huggingface.js"; import type { ApplyAuthChoiceParams, ApplyAuthChoiceResult } from "./auth-choice.apply.js"; import { applyAuthChoiceOpenRouter } from "./auth-choice.apply.openrouter.js"; import { applyDefaultModelChoice } from "./auth-choice.default-model.js"; import { applyGoogleGeminiModelDefault, GOOGLE_GEMINI_DEFAULT_MODEL, } from "./google-gemini-model-default.js"; import { applyAuthProfileConfig, applyCloudflareAiGatewayConfig, applyCloudflareAiGatewayProviderConfig, applyQianfanConfig, applyQianfanProviderConfig, applyKimiCodeConfig, applyKimiCodeProviderConfig, applyLitellmConfig, applyLitellmProviderConfig, applyMoonshotConfig, applyMoonshotConfigCn, applyMoonshotProviderConfig, applyMoonshotProviderConfigCn, applyOpencodeZenConfig, applyOpencodeZenProviderConfig, applySyntheticConfig, applySyntheticProviderConfig, applyTogetherConfig, applyTogetherProviderConfig, applyVeniceConfig, applyVeniceProviderConfig, applyVercelAiGatewayConfig, applyVercelAiGatewayProviderConfig, applyXiaomiConfig, applyXiaomiProviderConfig, applyZaiConfig, applyZaiProviderConfig, CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, LITELLM_DEFAULT_MODEL_REF, QIANFAN_DEFAULT_MODEL_REF, KIMI_CODING_MODEL_REF, MOONSHOT_DEFAULT_MODEL_REF, SYNTHETIC_DEFAULT_MODEL_REF, TOGETHER_DEFAULT_MODEL_REF, VENICE_DEFAULT_MODEL_REF, VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, XIAOMI_DEFAULT_MODEL_REF, setCloudflareAiGatewayConfig, setQianfanApiKey, setGeminiApiKey, setLitellmApiKey, setKimiCodingApiKey, setMoonshotApiKey, setOpencodeZenApiKey, setSyntheticApiKey, setTogetherApiKey, setVeniceApiKey, setVercelAiGatewayApiKey, setXiaomiApiKey, setZaiApiKey, ZAI_DEFAULT_MODEL_REF, } from "./onboard-auth.js"; import { OPENCODE_ZEN_DEFAULT_MODEL } from "./opencode-zen-model-default.js"; import { detectZaiEndpoint } from "./zai-endpoint-detect.js"; export async function applyAuthChoiceApiProviders( params: ApplyAuthChoiceParams, ): Promise { let nextConfig = params.config; let agentModelOverride: string | undefined; const noteAgentModel = async (model: string) => { if (!params.agentId) { return; } await params.prompter.note( `Default model set to ${model} for agent "${params.agentId}".`, "Model configured", ); }; let authChoice = params.authChoice; if ( authChoice === "apiKey" && params.opts?.tokenProvider && params.opts.tokenProvider !== "anthropic" && params.opts.tokenProvider !== "openai" ) { if (params.opts.tokenProvider === "openrouter") { authChoice = "openrouter-api-key"; } else if (params.opts.tokenProvider === "litellm") { authChoice = "litellm-api-key"; } else if (params.opts.tokenProvider === "vercel-ai-gateway") { authChoice = "ai-gateway-api-key"; } else if (params.opts.tokenProvider === "cloudflare-ai-gateway") { authChoice = "cloudflare-ai-gateway-api-key"; } else if (params.opts.tokenProvider === "moonshot") { authChoice = "moonshot-api-key"; } else if ( params.opts.tokenProvider === "kimi-code" || params.opts.tokenProvider === "kimi-coding" ) { authChoice = "kimi-code-api-key"; } else if (params.opts.tokenProvider === "google") { authChoice = "gemini-api-key"; } else if (params.opts.tokenProvider === "zai") { authChoice = "zai-api-key"; } else if (params.opts.tokenProvider === "xiaomi") { authChoice = "xiaomi-api-key"; } else if (params.opts.tokenProvider === "synthetic") { authChoice = "synthetic-api-key"; } else if (params.opts.tokenProvider === "venice") { authChoice = "venice-api-key"; } else if (params.opts.tokenProvider === "together") { authChoice = "together-api-key"; } else if (params.opts.tokenProvider === "huggingface") { authChoice = "huggingface-api-key"; } else if (params.opts.tokenProvider === "opencode") { authChoice = "opencode-zen"; } else if (params.opts.tokenProvider === "qianfan") { authChoice = "qianfan-api-key"; } } async function ensureMoonshotApiKeyCredential(promptMessage: string): Promise { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "moonshot") { await setMoonshotApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } const envKey = resolveEnvApiKey("moonshot"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing MOONSHOT_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setMoonshotApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: promptMessage, validate: validateApiKeyInput, }); await setMoonshotApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } } if (authChoice === "openrouter-api-key") { return applyAuthChoiceOpenRouter(params); } if (authChoice === "litellm-api-key") { const store = ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false }); const profileOrder = resolveAuthProfileOrder({ cfg: nextConfig, store, provider: "litellm" }); const existingProfileId = profileOrder.find((profileId) => Boolean(store.profiles[profileId])); const existingCred = existingProfileId ? store.profiles[existingProfileId] : undefined; let profileId = "litellm:default"; let hasCredential = false; if (existingProfileId && existingCred?.type === "api_key") { profileId = existingProfileId; hasCredential = true; } if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "litellm") { await setLitellmApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } if (!hasCredential) { await params.prompter.note( "LiteLLM provides a unified API to 100+ LLM providers.\nGet your API key from your LiteLLM proxy or https://litellm.ai\nDefault proxy runs on http://localhost:4000", "LiteLLM", ); const envKey = resolveEnvApiKey("litellm"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing LITELLM_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setLitellmApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter LiteLLM API key", validate: validateApiKeyInput, }); await setLitellmApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); hasCredential = true; } } if (hasCredential) { nextConfig = applyAuthProfileConfig(nextConfig, { profileId, provider: "litellm", mode: "api_key", }); } const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: LITELLM_DEFAULT_MODEL_REF, applyDefaultConfig: applyLitellmConfig, applyProviderConfig: applyLitellmProviderConfig, noteDefault: LITELLM_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; return { config: nextConfig, agentModelOverride }; } if (authChoice === "ai-gateway-api-key") { let hasCredential = false; if ( !hasCredential && params.opts?.token && params.opts?.tokenProvider === "vercel-ai-gateway" ) { await setVercelAiGatewayApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } const envKey = resolveEnvApiKey("vercel-ai-gateway"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing AI_GATEWAY_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setVercelAiGatewayApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Vercel AI Gateway API key", validate: validateApiKeyInput, }); await setVercelAiGatewayApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "vercel-ai-gateway:default", provider: "vercel-ai-gateway", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, applyDefaultConfig: applyVercelAiGatewayConfig, applyProviderConfig: applyVercelAiGatewayProviderConfig, noteDefault: VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "cloudflare-ai-gateway-api-key") { let hasCredential = false; let accountId = params.opts?.cloudflareAiGatewayAccountId?.trim() ?? ""; let gatewayId = params.opts?.cloudflareAiGatewayGatewayId?.trim() ?? ""; const ensureAccountGateway = async () => { if (!accountId) { const value = await params.prompter.text({ message: "Enter Cloudflare Account ID", validate: (val) => (String(val ?? "").trim() ? undefined : "Account ID is required"), }); accountId = String(value ?? "").trim(); } if (!gatewayId) { const value = await params.prompter.text({ message: "Enter Cloudflare AI Gateway ID", validate: (val) => (String(val ?? "").trim() ? undefined : "Gateway ID is required"), }); gatewayId = String(value ?? "").trim(); } }; const optsApiKey = normalizeApiKeyInput(params.opts?.cloudflareAiGatewayApiKey ?? ""); if (!hasCredential && accountId && gatewayId && optsApiKey) { await setCloudflareAiGatewayConfig(accountId, gatewayId, optsApiKey, params.agentDir); hasCredential = true; } const envKey = resolveEnvApiKey("cloudflare-ai-gateway"); if (!hasCredential && envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing CLOUDFLARE_AI_GATEWAY_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await ensureAccountGateway(); await setCloudflareAiGatewayConfig( accountId, gatewayId, normalizeApiKeyInput(envKey.apiKey), params.agentDir, ); hasCredential = true; } } if (!hasCredential && optsApiKey) { await ensureAccountGateway(); await setCloudflareAiGatewayConfig(accountId, gatewayId, optsApiKey, params.agentDir); hasCredential = true; } if (!hasCredential) { await ensureAccountGateway(); const key = await params.prompter.text({ message: "Enter Cloudflare AI Gateway API key", validate: validateApiKeyInput, }); await setCloudflareAiGatewayConfig( accountId, gatewayId, normalizeApiKeyInput(String(key ?? "")), params.agentDir, ); hasCredential = true; } if (hasCredential) { nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "cloudflare-ai-gateway:default", provider: "cloudflare-ai-gateway", mode: "api_key", }); } { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, applyDefaultConfig: (cfg) => applyCloudflareAiGatewayConfig(cfg, { accountId: accountId || params.opts?.cloudflareAiGatewayAccountId, gatewayId: gatewayId || params.opts?.cloudflareAiGatewayGatewayId, }), applyProviderConfig: (cfg) => applyCloudflareAiGatewayProviderConfig(cfg, { accountId: accountId || params.opts?.cloudflareAiGatewayAccountId, gatewayId: gatewayId || params.opts?.cloudflareAiGatewayGatewayId, }), noteDefault: CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "moonshot-api-key") { await ensureMoonshotApiKeyCredential("Enter Moonshot API key"); nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "moonshot:default", provider: "moonshot", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: MOONSHOT_DEFAULT_MODEL_REF, applyDefaultConfig: applyMoonshotConfig, applyProviderConfig: applyMoonshotProviderConfig, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "moonshot-api-key-cn") { await ensureMoonshotApiKeyCredential("Enter Moonshot API key (.cn)"); nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "moonshot:default", provider: "moonshot", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: MOONSHOT_DEFAULT_MODEL_REF, applyDefaultConfig: applyMoonshotConfigCn, applyProviderConfig: applyMoonshotProviderConfigCn, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "kimi-code-api-key") { let hasCredential = false; const tokenProvider = params.opts?.tokenProvider?.trim().toLowerCase(); if ( !hasCredential && params.opts?.token && (tokenProvider === "kimi-code" || tokenProvider === "kimi-coding") ) { await setKimiCodingApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } if (!hasCredential) { await params.prompter.note( [ "Kimi Coding uses a dedicated endpoint and API key.", "Get your API key at: https://www.kimi.com/code/en", ].join("\n"), "Kimi Coding", ); } const envKey = resolveEnvApiKey("kimi-coding"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing KIMI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setKimiCodingApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Kimi Coding API key", validate: validateApiKeyInput, }); await setKimiCodingApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "kimi-coding:default", provider: "kimi-coding", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: KIMI_CODING_MODEL_REF, applyDefaultConfig: applyKimiCodeConfig, applyProviderConfig: applyKimiCodeProviderConfig, noteDefault: KIMI_CODING_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "gemini-api-key") { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "google") { await setGeminiApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } const envKey = resolveEnvApiKey("google"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing GEMINI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setGeminiApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Gemini API key", validate: validateApiKeyInput, }); await setGeminiApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "google:default", provider: "google", mode: "api_key", }); if (params.setDefaultModel) { const applied = applyGoogleGeminiModelDefault(nextConfig); nextConfig = applied.next; if (applied.changed) { await params.prompter.note( `Default model set to ${GOOGLE_GEMINI_DEFAULT_MODEL}`, "Model configured", ); } } else { agentModelOverride = GOOGLE_GEMINI_DEFAULT_MODEL; await noteAgentModel(GOOGLE_GEMINI_DEFAULT_MODEL); } return { config: nextConfig, agentModelOverride }; } if ( authChoice === "zai-api-key" || authChoice === "zai-coding-global" || authChoice === "zai-coding-cn" || authChoice === "zai-global" || authChoice === "zai-cn" ) { let endpoint: "global" | "cn" | "coding-global" | "coding-cn" | undefined; if (authChoice === "zai-coding-global") { endpoint = "coding-global"; } else if (authChoice === "zai-coding-cn") { endpoint = "coding-cn"; } else if (authChoice === "zai-global") { endpoint = "global"; } else if (authChoice === "zai-cn") { endpoint = "cn"; } // Input API key let hasCredential = false; let apiKey = ""; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "zai") { apiKey = normalizeApiKeyInput(params.opts.token); await setZaiApiKey(apiKey, params.agentDir); hasCredential = true; } const envKey = resolveEnvApiKey("zai"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing ZAI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { apiKey = envKey.apiKey; await setZaiApiKey(apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Z.AI API key", validate: validateApiKeyInput, }); apiKey = normalizeApiKeyInput(String(key ?? "")); await setZaiApiKey(apiKey, params.agentDir); } // zai-api-key: auto-detect endpoint + choose a working default model. let modelIdOverride: string | undefined; if (!endpoint) { const detected = await detectZaiEndpoint({ apiKey }); if (detected) { endpoint = detected.endpoint; modelIdOverride = detected.modelId; await params.prompter.note(detected.note, "Z.AI endpoint"); } else { endpoint = await params.prompter.select({ message: "Select Z.AI endpoint", options: [ { value: "coding-global", label: "Coding-Plan-Global", hint: "GLM Coding Plan Global (api.z.ai)", }, { value: "coding-cn", label: "Coding-Plan-CN", hint: "GLM Coding Plan CN (open.bigmodel.cn)", }, { value: "global", label: "Global", hint: "Z.AI Global (api.z.ai)", }, { value: "cn", label: "CN", hint: "Z.AI CN (open.bigmodel.cn)", }, ], initialValue: "global", }); } } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "zai:default", provider: "zai", mode: "api_key", }); const defaultModel = modelIdOverride ? `zai/${modelIdOverride}` : ZAI_DEFAULT_MODEL_REF; const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel, applyDefaultConfig: (config) => applyZaiConfig(config, { endpoint, ...(modelIdOverride ? { modelId: modelIdOverride } : {}), }), applyProviderConfig: (config) => applyZaiProviderConfig(config, { endpoint, ...(modelIdOverride ? { modelId: modelIdOverride } : {}), }), noteDefault: defaultModel, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; return { config: nextConfig, agentModelOverride }; } if (authChoice === "xiaomi-api-key") { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "xiaomi") { await setXiaomiApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } const envKey = resolveEnvApiKey("xiaomi"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing XIAOMI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setXiaomiApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Xiaomi API key", validate: validateApiKeyInput, }); await setXiaomiApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "xiaomi:default", provider: "xiaomi", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: XIAOMI_DEFAULT_MODEL_REF, applyDefaultConfig: applyXiaomiConfig, applyProviderConfig: applyXiaomiProviderConfig, noteDefault: XIAOMI_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "synthetic-api-key") { if (params.opts?.token && params.opts?.tokenProvider === "synthetic") { await setSyntheticApiKey(String(params.opts.token ?? "").trim(), params.agentDir); } else { const key = await params.prompter.text({ message: "Enter Synthetic API key", validate: (value) => (value?.trim() ? undefined : "Required"), }); await setSyntheticApiKey(String(key ?? "").trim(), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "synthetic:default", provider: "synthetic", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: SYNTHETIC_DEFAULT_MODEL_REF, applyDefaultConfig: applySyntheticConfig, applyProviderConfig: applySyntheticProviderConfig, noteDefault: SYNTHETIC_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "venice-api-key") { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "venice") { await setVeniceApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } if (!hasCredential) { await params.prompter.note( [ "Venice AI provides privacy-focused inference with uncensored models.", "Get your API key at: https://venice.ai/settings/api", "Supports 'private' (fully private) and 'anonymized' (proxy) modes.", ].join("\n"), "Venice AI", ); } const envKey = resolveEnvApiKey("venice"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing VENICE_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setVeniceApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Venice AI API key", validate: validateApiKeyInput, }); await setVeniceApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "venice:default", provider: "venice", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: VENICE_DEFAULT_MODEL_REF, applyDefaultConfig: applyVeniceConfig, applyProviderConfig: applyVeniceProviderConfig, noteDefault: VENICE_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "opencode-zen") { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "opencode") { await setOpencodeZenApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } if (!hasCredential) { await params.prompter.note( [ "OpenCode Zen provides access to Claude, GPT, Gemini, and more models.", "Get your API key at: https://opencode.ai/auth", "OpenCode Zen bills per request. Check your OpenCode dashboard for details.", ].join("\n"), "OpenCode Zen", ); } const envKey = resolveEnvApiKey("opencode"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing OPENCODE_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setOpencodeZenApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter OpenCode Zen API key", validate: validateApiKeyInput, }); await setOpencodeZenApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "opencode:default", provider: "opencode", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: OPENCODE_ZEN_DEFAULT_MODEL, applyDefaultConfig: applyOpencodeZenConfig, applyProviderConfig: applyOpencodeZenProviderConfig, noteDefault: OPENCODE_ZEN_DEFAULT_MODEL, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "together-api-key") { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "together") { await setTogetherApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } if (!hasCredential) { await params.prompter.note( [ "Together AI provides access to leading open-source models including Llama, DeepSeek, Qwen, and more.", "Get your API key at: https://api.together.xyz/settings/api-keys", ].join("\n"), "Together AI", ); } const envKey = resolveEnvApiKey("together"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing TOGETHER_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { await setTogetherApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter Together AI API key", validate: validateApiKeyInput, }); await setTogetherApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "together:default", provider: "together", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: TOGETHER_DEFAULT_MODEL_REF, applyDefaultConfig: applyTogetherConfig, applyProviderConfig: applyTogetherProviderConfig, noteDefault: TOGETHER_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } if (authChoice === "huggingface-api-key") { return applyAuthChoiceHuggingface({ ...params, authChoice }); } if (authChoice === "qianfan-api-key") { let hasCredential = false; if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "qianfan") { setQianfanApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir); hasCredential = true; } if (!hasCredential) { await params.prompter.note( [ "Get your API key at: https://console.bce.baidu.com/qianfan/ais/console/apiKey", "API key format: bce-v3/ALTAK-...", ].join("\n"), "QIANFAN", ); } const envKey = resolveEnvApiKey("qianfan"); if (envKey) { const useExisting = await params.prompter.confirm({ message: `Use existing QIANFAN_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`, initialValue: true, }); if (useExisting) { setQianfanApiKey(envKey.apiKey, params.agentDir); hasCredential = true; } } if (!hasCredential) { const key = await params.prompter.text({ message: "Enter QIANFAN API key", validate: validateApiKeyInput, }); setQianfanApiKey(normalizeApiKeyInput(String(key ?? "")), params.agentDir); } nextConfig = applyAuthProfileConfig(nextConfig, { profileId: "qianfan:default", provider: "qianfan", mode: "api_key", }); { const applied = await applyDefaultModelChoice({ config: nextConfig, setDefaultModel: params.setDefaultModel, defaultModel: QIANFAN_DEFAULT_MODEL_REF, applyDefaultConfig: applyQianfanConfig, applyProviderConfig: applyQianfanProviderConfig, noteDefault: QIANFAN_DEFAULT_MODEL_REF, noteAgentModel, prompter: params.prompter, }); nextConfig = applied.config; agentModelOverride = applied.agentModelOverride ?? agentModelOverride; } return { config: nextConfig, agentModelOverride }; } return null; }