import { getAuthTokenSource, getConfiguredAuthProvider, getOpenAIApiKeyWithSource, getOpenCodeApiKeyWithSource, getNvidiaApiKeyWithSource, getOpenRouterApiKeyWithSource, hasAnthropicApiKeyAuth, } from "./auth.js"; import type { GlobalConfig } from "./config.js"; import { getAPIProvider, type APIProvider } from "./model/providers.js"; export const AUTH_PROVIDER_CHOICES = [ "anthropic", "openai", "openrouter", "opencode", "nvidia", ] as const; export type AuthProviderChoice = (typeof AUTH_PROVIDER_CHOICES)[number]; type AuthProviderMetadata = { id: AuthProviderChoice; label: string; description: string; setupHint: string; }; const AUTH_PROVIDER_METADATA: Record = { anthropic: { id: "anthropic", label: "Anthropic", description: "Subscription login, Console API billing, or Anthropic-compatible platforms", setupHint: "Run /login and choose Anthropic, or use mervelas auth login.", }, openai: { id: "openai", label: "OpenAI / Codex", description: "Codex login, imported Codex auth, or an OpenAI API key", setupHint: "Run /login and choose OpenAI, or set OPENAI_API_KEY / OPENAI_ACCESS_TOKEN / CODEX_ACCESS_TOKEN.", }, openrouter: { id: "openrouter", label: "OpenRouter", description: "OpenRouter API key using the Responses API integration", setupHint: "Run /login and choose OpenRouter, or set OPENROUTER_API_KEY.", }, opencode: { id: "opencode", label: "OpenCode Zen", description: "Curated OpenCode gateway models, including some free keyless models", setupHint: "Run /login and choose OpenCode Zen, set OPENCODE_API_KEY, or use a free keyless Zen model.", }, nvidia: { id: "nvidia", label: "NVIDIA NIM", description: "NVIDIA Inference Microservices, offering a variety of LLMs (many available for free)", setupHint: "Run /login and choose NVIDIA NIM, set NVIDIA_API_KEY, or use a free keyless NVIDIA NIM model.", }, }; export function isAuthProviderChoice( value: string, ): value is AuthProviderChoice { return AUTH_PROVIDER_CHOICES.includes(value as AuthProviderChoice); } export function getAuthProviderMetadata( provider: AuthProviderChoice, ): AuthProviderMetadata { return AUTH_PROVIDER_METADATA[provider]; } export function renderAuthProviderName(provider: AuthProviderChoice): string { return getAuthProviderMetadata(provider).label; } export function getAuthProviderDescription( provider: AuthProviderChoice, ): string { return getAuthProviderMetadata(provider).description; } export function getProviderSetupHint(provider: AuthProviderChoice): string { return getAuthProviderMetadata(provider).setupHint; } export function hasConfiguredCredentialsForProvider( provider: AuthProviderChoice, ): boolean { if (provider === "anthropic") { return getAuthTokenSource().hasToken || hasAnthropicApiKeyAuth(); } if (provider === "openai") { return getOpenAIApiKeyWithSource().source !== "none"; } if (provider === "openrouter") { return getOpenRouterApiKeyWithSource().source !== "none"; } if (provider === "nvidia") { return getNvidiaApiKeyWithSource().source !== "none"; } return getOpenCodeApiKeyWithSource().source !== "none"; } export function getAuthProviderFromApiProvider( provider: APIProvider, ): AuthProviderChoice { return provider === "firstParty" ? "anthropic" : provider; } export function setPreferredAuthProvider( config: GlobalConfig, provider: AuthProviderChoice, ): GlobalConfig { return { ...config, authProvider: provider, }; } export function getProviderStatusText(): string { const configuredProvider = getConfiguredAuthProvider(); const activeProvider = getAuthProviderFromApiProvider(getAPIProvider()); const readiness = hasConfiguredCredentialsForProvider(configuredProvider) ? "configured" : "not configured yet"; if (activeProvider === configuredProvider) { return `Current provider: ${renderAuthProviderName(configuredProvider)} (${readiness})`; } return `Preferred provider: ${renderAuthProviderName(configuredProvider)} (${readiness}) ยท Active provider: ${renderAuthProviderName(activeProvider)}`; }