import { normalizeProviderIdForAuth } from "../agents/model-selection.js"; import type { OpenClawConfig } from "../config/config.js"; import { loadPluginManifestRegistry } from "./manifest-registry.js"; export type ProviderAuthChoiceMetadata = { pluginId: string; providerId: string; methodId: string; choiceId: string; choiceLabel: string; choiceHint?: string; deprecatedChoiceIds?: string[]; groupId?: string; groupLabel?: string; groupHint?: string; optionKey?: string; cliFlag?: string; cliOption?: string; cliDescription?: string; onboardingScopes?: ("text-inference" | "image-generation")[]; }; export type ProviderOnboardAuthFlag = { optionKey: string; authChoice: string; cliFlag: string; cliOption: string; description: string; }; export function resolveManifestProviderAuthChoices(params?: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; }): ProviderAuthChoiceMetadata[] { const registry = loadPluginManifestRegistry({ config: params?.config, workspaceDir: params?.workspaceDir, env: params?.env, }); return registry.plugins.flatMap((plugin) => (plugin.providerAuthChoices ?? []).map((choice) => ({ pluginId: plugin.id, providerId: choice.provider, methodId: choice.method, choiceId: choice.choiceId, choiceLabel: choice.choiceLabel ?? choice.choiceId, ...(choice.choiceHint ? { choiceHint: choice.choiceHint } : {}), ...(choice.deprecatedChoiceIds ? { deprecatedChoiceIds: choice.deprecatedChoiceIds } : {}), ...(choice.groupId ? { groupId: choice.groupId } : {}), ...(choice.groupLabel ? { groupLabel: choice.groupLabel } : {}), ...(choice.groupHint ? { groupHint: choice.groupHint } : {}), ...(choice.optionKey ? { optionKey: choice.optionKey } : {}), ...(choice.cliFlag ? { cliFlag: choice.cliFlag } : {}), ...(choice.cliOption ? { cliOption: choice.cliOption } : {}), ...(choice.cliDescription ? { cliDescription: choice.cliDescription } : {}), ...(choice.onboardingScopes ? { onboardingScopes: choice.onboardingScopes } : {}), })), ); } export function resolveManifestProviderAuthChoice( choiceId: string, params?: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; }, ): ProviderAuthChoiceMetadata | undefined { const normalized = choiceId.trim(); if (!normalized) { return undefined; } return resolveManifestProviderAuthChoices(params).find( (choice) => choice.choiceId === normalized, ); } export function resolveManifestProviderApiKeyChoice(params: { providerId: string; config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; }): ProviderAuthChoiceMetadata | undefined { const normalizedProviderId = normalizeProviderIdForAuth(params.providerId); if (!normalizedProviderId) { return undefined; } return resolveManifestProviderAuthChoices(params).find((choice) => { if (!choice.optionKey) { return false; } return normalizeProviderIdForAuth(choice.providerId) === normalizedProviderId; }); } export function resolveManifestDeprecatedProviderAuthChoice( choiceId: string, params?: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; }, ): ProviderAuthChoiceMetadata | undefined { const normalized = choiceId.trim(); if (!normalized) { return undefined; } return resolveManifestProviderAuthChoices(params).find((choice) => choice.deprecatedChoiceIds?.includes(normalized), ); } export function resolveManifestProviderOnboardAuthFlags(params?: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; }): ProviderOnboardAuthFlag[] { const flags: ProviderOnboardAuthFlag[] = []; const seen = new Set(); for (const choice of resolveManifestProviderAuthChoices(params)) { if (!choice.optionKey || !choice.cliFlag || !choice.cliOption) { continue; } const dedupeKey = `${choice.optionKey}::${choice.cliFlag}`; if (seen.has(dedupeKey)) { continue; } seen.add(dedupeKey); flags.push({ optionKey: choice.optionKey, authChoice: choice.choiceId, cliFlag: choice.cliFlag, cliOption: choice.cliOption, description: choice.cliDescription ?? choice.choiceLabel, }); } return flags; }