Files
openclaw/src/plugins/provider-authentication.types.ts
Peter Steinberger da59d6ade9 feat(onboarding): detect local inference providers (#108605)
* feat(onboarding): detect local inference providers

* fix(onboarding): satisfy inference choice lint

* chore(i18n): refresh onboarding locales

* chore: leave changelog to release automation

* chore(plugin-sdk): refresh API baseline

* fix(onboarding): preserve source config during local activation
2026-07-15 22:46:16 -07:00

264 lines
8.6 KiB
TypeScript

import type { ApiKeyCredential, AuthProfileCredential } from "../agents/auth-profiles/types.js";
import type { PromptMode } from "../agents/system-prompt.types.js";
import type { ModelProviderConfig } from "../config/types.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import type { SecretInputMode } from "./provider-auth-types.js";
import type { ProviderAuthOptionBag } from "./provider-external-auth.types.js";
import type { createVpsAwareOAuthHandlers } from "./provider-oauth-flow.js";
export type ProviderAuthKind = "oauth" | "api_key" | "token" | "device_code" | "custom";
/** Standard result payload returned by provider auth methods. */
export type ProviderAuthResult = {
profiles: Array<{ profileId: string; credential: AuthProfileCredential }>;
/**
* Optional config patch to merge after credentials are written.
*
* Use this for provider-owned onboarding defaults such as
* `models.providers.<id>` entries, default aliases, or agent model helpers.
* The caller still persists auth-profile bindings separately.
*/
configPatch?: Partial<OpenClawConfig>;
defaultModel?: string;
notes?: string[];
/**
* Opt in to replace `agents.defaults.models` wholesale with the patch map.
* Default behavior merges the map so other providers' entries survive.
* Set only from migrations that intentionally rename/remove model keys.
*/
replaceDefaultModels?: boolean;
};
/** Interactive auth context passed to provider login/setup methods. */
export type ProviderAuthContext = {
config: OpenClawConfig;
env?: NodeJS.ProcessEnv;
agentDir?: string;
workspaceDir?: string;
prompter: WizardPrompter;
runtime: RuntimeEnv;
/** Cancels browser callbacks, device polling, and other app-owned auth work. */
signal?: AbortSignal;
/**
* Optional onboarding CLI options that triggered this auth flow.
*
* Present for setup/configure/auth-choice flows so provider methods can
* honor preseeded flags like `--openai-api-key` or generic
* `--token/--token-provider` pairs. Direct `models auth login` usually
* leaves this undefined.
*/
opts?: ProviderAuthOptionBag;
/**
* Onboarding secret persistence preference.
*
* Interactive wizard flows set this when the caller explicitly requested
* plaintext or env/file/exec ref storage. Ad-hoc `models auth login` flows
* usually leave it undefined.
*/
secretInputMode?: SecretInputMode;
/**
* Whether the provider auth flow should offer the onboarding secret-storage
* mode picker when `secretInputMode` is unset.
*
* This is true for onboarding/configure flows and false for direct
* `models auth` commands, which should keep a tighter, provider-owned prompt
* surface.
*/
allowSecretRefPrompt?: boolean;
isRemote: boolean;
openUrl: (url: string) => Promise<void>;
oauth: {
createVpsAwareHandlers: typeof createVpsAwareOAuthHandlers;
};
};
export type ProviderNonInteractiveApiKeyResult = {
key: string;
source: "profile" | "env" | "flag";
envVarName?: string;
};
export type ProviderResolveNonInteractiveApiKeyParams = {
provider: string;
flagValue?: string;
flagName: `--${string}`;
envVar: string;
envVarName?: string;
allowProfile?: boolean;
required?: boolean;
};
export type ProviderNonInteractiveApiKeyCredentialParams = {
provider: string;
resolved: ProviderNonInteractiveApiKeyResult;
email?: string;
metadata?: Record<string, string>;
};
export type ProviderAuthMethodNonInteractiveContext = {
authChoice: string;
config: OpenClawConfig;
baseConfig: OpenClawConfig;
opts: ProviderAuthOptionBag;
runtime: RuntimeEnv;
agentDir?: string;
workspaceDir?: string;
resolveApiKey: (
params: ProviderResolveNonInteractiveApiKeyParams,
) => Promise<ProviderNonInteractiveApiKeyResult | null>;
toApiKeyCredential: (
params: ProviderNonInteractiveApiKeyCredentialParams,
) => ApiKeyCredential | null;
};
/** Read-only context for app-guided discovery of already available inference. */
export type ProviderAppGuidedSetupContext = {
config: OpenClawConfig;
env: NodeJS.ProcessEnv;
workspaceDir?: string;
signal?: AbortSignal;
};
export type ProviderAppGuidedSetupCandidate = {
/** Canonical provider/model reference returned unchanged during activation. */
modelRef: string;
/** Optional provider-owned detail shown beside the auth-choice label. */
detail?: string;
};
export type ProviderAppGuidedSetup = {
/** Detection is read-only: no model pull, download, login, or config write. */
detect: (ctx: ProviderAppGuidedSetupContext) => Promise<ProviderAppGuidedSetupCandidate | null>;
/** Recheck one detected model and return the config required for a live probe. */
prepare: (
ctx: ProviderAppGuidedSetupContext & { modelRef: string },
) => Promise<ProviderAuthResult | null>;
};
export type ProviderAuthMethod = {
id: string;
label: string;
hint?: string;
kind: ProviderAuthKind;
/** Provider-owned model used to validate app-guided secret setup. */
starterModel?: string;
/**
* Optional wizard/onboarding metadata for this specific auth method.
*
* Use this when one provider exposes multiple setup entries (for example API
* key + OAuth, or region-specific login flows). OpenClaw uses this to expose
* method-specific auth choices while keeping the provider id stable.
*/
wizard?: ProviderPluginWizardSetup;
run: (ctx: ProviderAuthContext) => Promise<ProviderAuthResult>;
runNonInteractive?: (
ctx: ProviderAuthMethodNonInteractiveContext,
) => Promise<OpenClawConfig | null>;
/** Provider-owned local model discovery for the shared guided setup ladder. */
appGuidedSetup?: ProviderAppGuidedSetup;
};
export type ProviderPluginWizardSetup = {
choiceId?: string;
choiceLabel?: string;
choiceHint?: string;
assistantPriority?: number;
assistantVisibility?: "visible" | "manual-only";
onboardingFeatured?: boolean;
groupId?: string;
groupLabel?: string;
groupHint?: string;
methodId?: string;
/**
* Interactive onboarding surfaces where this auth choice should appear.
* Defaults to `["text-inference"]` when omitted.
*/
onboardingScopes?: Array<"text-inference" | "image-generation" | "music-generation">;
/**
* Optional model-allowlist prompt policy applied after this auth choice is
* selected in configure/onboarding flows.
*
* Keep this UI-facing and static. Provider logic that needs runtime state
* should stay in `run`/`runNonInteractive`.
*/
modelAllowlist?: {
allowedKeys?: string[];
initialSelections?: string[];
loadCatalog?: boolean;
message?: string;
};
/**
* Optional default-model prompt policy for this auth/setup choice.
*
* Use this when selecting the auth choice should still force a model picker
* even if the choice was preseeded via CLI/configure, or when "keep current"
* would skip required provider-owned post-selection work.
*/
modelSelection?: {
promptWhenAuthChoiceProvided?: boolean;
allowKeepCurrent?: boolean;
};
};
/** Optional model-picker metadata shown in interactive provider selection flows. */
export type ProviderPluginWizardModelPicker = {
label?: string;
hint?: string;
methodId?: string;
};
/** UI metadata that lets provider plugins appear in onboarding and configure flows. */
export type ProviderPluginWizard = {
setup?: ProviderPluginWizardSetup;
modelPicker?: ProviderPluginWizardModelPicker;
};
export type ProviderOAuthProfileIdRepair = {
/**
* Legacy OAuth profile id to migrate away from.
*
* When omitted, OpenClaw falls back to `<provider>:default`.
*/
legacyProfileId?: string;
/**
* Optional custom doctor prompt label.
*
* Defaults to the provider label when omitted.
*/
promptLabel?: string;
};
export type ProviderModelSelectedContext = {
config: OpenClawConfig;
model: string;
prompter: WizardPrompter;
agentDir?: string;
workspaceDir?: string;
};
export type ProviderDeferSyntheticProfileAuthContext = {
config?: OpenClawConfig;
provider: string;
providerConfig?: ModelProviderConfig;
resolvedApiKey?: string;
};
export type ProviderSystemPromptContributionContext = {
config?: OpenClawConfig;
agentDir?: string;
workspaceDir?: string;
provider: string;
modelId: string;
promptMode: PromptMode;
runtimeChannel?: string;
runtimeCapabilities?: string[];
agentId?: string;
trigger?: "cron" | "heartbeat" | "manual" | "memory" | "overflow" | "user";
};
export type ProviderTransformSystemPromptContext = ProviderSystemPromptContributionContext & {
systemPrompt: string;
};