import { getProviders } from "@earendil-works/pi-ai"; import type { AuthProviderOption, AuthProviderStatus, AuthType } from "../../shared/apiTypes.js"; const OAUTH_ONLY_PROVIDERS = new Set(["github-copilot", "openai-codex"]); const BUILT_IN_MODEL_PROVIDERS = new Set(getProviders()); export interface AuthProviderModelRegistry { authStorage: { getOAuthProviders(): { id: string; name: string }[]; list(): string[]; get(provider: string): { type: AuthType } | undefined; }; getAll(): { provider: string }[]; getProviderDisplayName(provider: string): string; getProviderAuthStatus(provider: string): AuthProviderStatus; } export function getLoginProviderOptions(modelRegistry: AuthProviderModelRegistry, authType?: AuthType): AuthProviderOption[] { const oauthProviders = modelRegistry.authStorage.getOAuthProviders(); const oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id)); const options: AuthProviderOption[] = oauthProviders.map((provider) => ({ id: provider.id, name: provider.name, authType: "oauth", status: modelRegistry.getProviderAuthStatus(provider.id), })); const modelProviders = new Set(modelRegistry.getAll().map((model) => model.provider)); for (const providerId of modelProviders) { if (!isApiKeyLoginProvider(providerId, oauthProviderIds)) continue; options.push({ id: providerId, name: modelRegistry.getProviderDisplayName(providerId), authType: "api_key", status: modelRegistry.getProviderAuthStatus(providerId), }); } return filterAndSort(options, authType); } export function getLogoutProviderOptions(modelRegistry: AuthProviderModelRegistry): AuthProviderOption[] { const options: AuthProviderOption[] = []; for (const providerId of modelRegistry.authStorage.list()) { const credential = modelRegistry.authStorage.get(providerId); if (credential === undefined) continue; options.push({ id: providerId, name: modelRegistry.getProviderDisplayName(providerId), authType: credential.type, status: modelRegistry.getProviderAuthStatus(providerId), }); } return filterAndSort(options); } export function isApiKeyLoginProvider(providerId: string, oauthProviderIds: ReadonlySet, builtInProviderIds: ReadonlySet = BUILT_IN_MODEL_PROVIDERS): boolean { if (OAUTH_ONLY_PROVIDERS.has(providerId)) return false; if (providerId === "anthropic") return true; if (oauthProviderIds.has(providerId)) return false; if (builtInProviderIds.has(providerId)) return true; return true; } function filterAndSort(options: AuthProviderOption[], authType?: AuthType): AuthProviderOption[] { const filtered = authType === undefined ? options : options.filter((option) => option.authType === authType); return filtered.sort((a, b) => a.name.localeCompare(b.name) || a.authType.localeCompare(b.authType) || a.id.localeCompare(b.id)); }