UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

700 lines (699 loc) 27.9 kB
import { o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js"; import { h as normalizeUniqueStringEntries } from "./string-normalization-DsCfAx8q.js"; import { c as resolveUserPath } from "./home-dir-BPhrG-aM.js"; import "./utils-P__uGsPB.js"; import { t as formatCliCommand } from "./command-format-C7YfyMTd.js"; import { v as resolveDefaultAgentDir } from "./agent-scope-config-DcbEhP0R.js"; import { r as normalizeProviderId } from "./provider-id-DMd-TDFp.js"; import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js"; import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js"; import { o as getRuntimeConfigSnapshot } from "./runtime-snapshot-BaQikjTR.js"; import "./config-Cs0XXL3x.js"; import { s as mintSecretSentinel } from "./sentinel-ZgmfESkJ.js"; import { n as resolveAuthStorePathForDisplay } from "./paths-DLuhw03H.js"; import { n as resolveApiKeyForProfile } from "./oauth-BNreHOU-.js"; import { n as SecretSurfaceUnavailableError } from "./runtime-degraded-state-D5EZZ925.js"; import { t as OAuthRefreshFailureError } from "./oauth-refresh-failure-DP-bO7C0.js"; import { f as resolveOwningPluginIdsForProviderRef } from "./providers-DCe4UB6a.js"; import { i as assertAuthProfileMigrationReady } from "./legacy-source-diagnostic-BNaogmw1.js"; import { r as ensureAuthProfileStore } from "./store-F1B2duCT.js"; import { n as listProfilesForProvider } from "./profile-list-DyfWX-d2.js"; import { a as resolveAuthProfileOrder } from "./order-CC2RBzI5.js"; import { c as isNonSecretApiKeyMarker, g as resolveProviderEnvAuthLookupMaps, n as CUSTOM_LOCAL_AUTH_MARKER } from "./model-auth-markers-jBKQn38x.js"; import { C as resolveProviderDeprecatedAuthProfileIds, I as shouldDeferProviderSyntheticProfileAuthWithPlugin, O as resolveProviderSyntheticAuthWithPlugin, i as buildProviderMissingAuthMessageWithPlugin, y as prepareProviderSyntheticAuthWithPlugin } from "./provider-runtime-BRJDPNgk.js"; import { r as resolveRuntimeSyntheticAuthProviderRefState } from "./synthetic-auth.runtime.js"; import { t as resolveEnvApiKey } from "./model-auth-env-Dq9W4xg9.js"; import { n as externalCliDiscoveryForProviderAuth } from "./external-cli-discovery-CbeZXk1q.js"; import { C as sentinelizeConfigSecretRefEnvApiKey, E as shouldUseImplicitAwsSdkAuth, S as resolveUsableCustomProviderApiKey, T as shouldPreferExplicitConfigApiKeyAuth, _ as resolveProviderConfig, a as hasSyntheticLocalProviderAuthConfig, b as resolveProviderEntryApiKeyProfileReference, c as isManagedSecretRefApiKeyMarker, d as resolveAwsSdkAuthInfo, f as resolveConfigAwareEnvApiKey, g as resolveProviderAuthOverride, h as resolveInlineProviderApiKeyCooldownUntil, i as hasSecretRefProviderApiKey, l as profileTypeToAuthMode, m as resolveDirectProviderCredentialMode, p as resolveConfiguredAwsSdkProfileAuth, s as isConfigBackedInlineProviderApiKey, t as assertInlineProviderApiKeyUsable, w as sentinelizeSecretRefProfileApiKey, y as resolveProviderEntryApiKeyBinding } from "./model-auth-provider-config-C_kr_q2g.js"; import { n as resolveManagedSecretRefRuntimeProviderAuth, t as assertRuntimeProviderSecretOwnerAvailable } from "./model-auth-runtime-config-DpvTPuUl.js"; import { n as ProviderAuthError } from "./model-auth-runtime-shared-C48YoQY0.js"; import "./auth-profiles-BdUEhE7u.js"; //#region src/agents/model-auth-openai.ts const OPENAI_PROVIDER_ID = "openai"; const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses"; function directOpenAIPlatformModelRequiresApiKey(params) { return normalizeProviderId(params.provider) === OPENAI_PROVIDER_ID && params.modelApi !== void 0 && normalizeLowercaseStringOrEmpty(params.modelApi) !== OPENAI_CODEX_RESPONSES_API; } function openAICodexTransportRequiresOAuth(params) { return normalizeProviderId(params.provider) === OPENAI_PROVIDER_ID && normalizeLowercaseStringOrEmpty(params.modelApi ?? "") === OPENAI_CODEX_RESPONSES_API; } function isAuthModeAllowedForModel(params) { if (openAICodexTransportRequiresOAuth(params)) return params.mode === "oauth" || params.mode === "token"; return !directOpenAIPlatformModelRequiresApiKey(params) || params.mode === "api-key"; } function assertAuthModeAllowedForModel(params) { if (isAuthModeAllowedForModel(params)) return; if (openAICodexTransportRequiresOAuth(params)) throw new Error(`Auth profile "${params.profileId}" uses ${params.mode} auth, but ${params.provider}/${params.modelApi} requires a ChatGPT subscription (OAuth or token) profile.`); throw new Error(`Auth profile "${params.profileId}" uses ${params.mode} auth, but ${params.provider}/${params.modelApi} requires an OpenAI API key profile.`); } //#endregion //#region src/agents/model-auth-runtime.ts /** * Snapshot-aware and synthetic provider-auth availability. */ /** Builds stable env/synthetic auth lookup data for repeated provider checks. */ function createRuntimeProviderAuthLookup(params) { const env = params.env ?? process.env; const lookupParams = { config: params.cfg, workspaceDir: params.workspaceDir, env }; const syntheticAuthProviderRefs = params.includePluginSyntheticAuth === false ? void 0 : resolveRuntimeSyntheticAuthProviderRefState(lookupParams); const authLookupMaps = resolveProviderEnvAuthLookupMaps(lookupParams); return { envApiKey: { aliasMap: authLookupMaps.aliasMap, candidateMap: authLookupMaps.envCandidateMap, authEvidenceMap: authLookupMaps.authEvidenceMap, skipSetupProviderFallback: true }, setupProviderFallbackRefs: authLookupMaps.setupProviderFallbackRefs, syntheticAuthProviderRefs: syntheticAuthProviderRefs?.complete ? syntheticAuthProviderRefs.refs : void 0, syntheticAuthProviderRefsComplete: syntheticAuthProviderRefs?.complete }; } function runtimeLookupAllowsSetupProviderFallback(params) { const refs = params.runtimeLookup?.setupProviderFallbackRefs; if (!refs?.length) return false; const normalizedProvider = normalizeProviderId(params.provider); const aliasTarget = params.runtimeLookup?.envApiKey.aliasMap?.[normalizedProvider]; return refs.includes(normalizedProvider) || (aliasTarget ? refs.includes(aliasTarget) : false); } function resolveRuntimeEnvApiKeyLookupOptions(params) { const envApiKey = params.runtimeLookup?.envApiKey; if (!envApiKey) return; const skipSetupProviderFallback = envApiKey.skipSetupProviderFallback === true ? !runtimeLookupAllowsSetupProviderFallback(params) : envApiKey.skipSetupProviderFallback; return { ...envApiKey, ...skipSetupProviderFallback !== void 0 ? { skipSetupProviderFallback } : {} }; } function listProviderSyntheticAuthRefs(params) { const refs = [params.provider]; const providerConfig = resolveProviderConfig(params.cfg, params.provider); if (params.modelApi) refs.push(params.modelApi); if (providerConfig?.api) refs.push(providerConfig.api); return normalizeUniqueStringEntries(refs.map((ref) => normalizeProviderId(ref))); } function shouldResolvePluginSyntheticAuth(params) { const syntheticAuthProviderRefs = params.runtimeLookup?.syntheticAuthProviderRefs; if (!syntheticAuthProviderRefs) return true; const eligibleRefs = new Set(normalizeUniqueStringEntries(syntheticAuthProviderRefs.map((ref) => normalizeProviderId(ref)))); if (eligibleRefs.size === 0) return false; return listProviderSyntheticAuthRefs(params).some((ref) => eligibleRefs.has(ref)); } function resolveRuntimeAvailableProviderAuth(params, resolveSyntheticAuth) { const provider = normalizeProviderId(params.provider); if (resolveProviderAuthOverride(params.cfg, provider) === "aws-sdk") return true; const inlineProviderApiKeyUsable = params.store ? (() => { const unusableUntil = resolveInlineProviderApiKeyCooldownUntil(params.store, provider); return unusableUntil === null || unusableUntil <= Date.now(); })() : true; const envAuth = resolveEnvApiKey(provider, params.env, { config: params.cfg, workspaceDir: params.workspaceDir, ...resolveRuntimeEnvApiKeyLookupOptions({ provider, runtimeLookup: params.runtimeLookup }) }); if (envAuth && isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: envAuth.source.includes("OAUTH_TOKEN") ? "oauth" : "api-key" }) && (!isConfigBackedInlineProviderApiKey({ cfg: params.cfg, provider, source: envAuth.source, store: params.store }) || inlineProviderApiKeyUsable)) return true; if (resolveUsableCustomProviderApiKey({ cfg: params.cfg, provider, env: params.env }) && inlineProviderApiKeyUsable) return true; const managedRuntimeAuth = resolveManagedSecretRefRuntimeProviderAuth({ cfg: params.cfg, provider }); if (managedRuntimeAuth && (!isConfigBackedInlineProviderApiKey({ cfg: params.cfg, provider, source: managedRuntimeAuth.source, store: params.store }) || inlineProviderApiKeyUsable)) return true; if (hasSyntheticLocalProviderAuthConfig({ cfg: params.cfg, provider })) return true; if (params.allowPluginSyntheticAuth !== false && shouldResolvePluginSyntheticAuth({ cfg: params.cfg, provider, runtimeLookup: params.runtimeLookup })) return resolveSyntheticAuth(provider); return false; } /** Fast auth-availability check for runtime provider/model selection. */ function hasRuntimeAvailableProviderAuth(params) { return resolveRuntimeAvailableProviderAuth(params, (provider) => Boolean(resolveSyntheticLocalProviderAuth({ cfg: params.cfg, provider, workspaceDir: params.workspaceDir, env: params.env }))); } /** Prepare external auth only after immediate credentials and discovery scope permit it. */ async function prepareRuntimeAvailableProviderAuth(params) { params.signal?.throwIfAborted(); return resolveRuntimeAvailableProviderAuth(params, async (provider) => Boolean(await prepareSyntheticLocalProviderAuth({ ...params, cfg: params.cfg, provider }))); } function syntheticAuthLookup(params, config) { return { provider: params.provider, config, workspaceDir: params.workspaceDir, env: params.env, modelApi: params.modelApi, context: { config, provider: params.provider, providerConfig: resolveProviderConfig(config, params.provider) } }; } function resolveProviderSyntheticRuntimeAuth(params, resolveFromConfig = (config) => resolveProviderSyntheticAuthWithPlugin(syntheticAuthLookup(params, config))) { const runtimeAuth = resolveManagedSecretRefRuntimeProviderAuth(params); if (runtimeAuth) return { auth: runtimeAuth }; if (hasSecretRefProviderApiKey(params.cfg, params.provider)) return { blockedOnManagedSecretRef: true }; const directAuth = resolveFromConfig(params.cfg); if (!directAuth) return {}; if (!isManagedSecretRefApiKeyMarker(directAuth.apiKey)) return { auth: directAuth }; const runtimeConfig = getRuntimeConfigSnapshot(); if (!runtimeConfig || runtimeConfig === params.cfg) return { blockedOnManagedSecretRef: true }; const runtimePluginAuth = resolveFromConfig(runtimeConfig); const runtimeApiKey = runtimePluginAuth?.apiKey; if (!runtimePluginAuth || !runtimeApiKey || isNonSecretApiKeyMarker(runtimeApiKey)) return { blockedOnManagedSecretRef: true }; return { auth: { ...runtimePluginAuth, apiKey: params.secretSentinels ? mintSecretSentinel(runtimeApiKey, { label: `model-auth:${params.provider}` }) : runtimeApiKey } }; } /** Prepare native readiness without widening explicit managed-credential authority. */ async function prepareSyntheticLocalProviderAuth(params) { if (params.allowPluginSyntheticAuth === false || hasSecretRefProviderApiKey(params.cfg, params.provider)) return resolveSyntheticLocalProviderAuth(params); const prepare = (config) => prepareProviderSyntheticAuthWithPlugin({ ...syntheticAuthLookup(params, config), signal: params.signal }); const direct = await prepare(params.cfg); const runtimeConfig = getRuntimeConfigSnapshot(); const runtimeAuth = direct && isManagedSecretRefApiKeyMarker(direct.apiKey) && runtimeConfig && runtimeConfig !== params.cfg ? await prepare(runtimeConfig) : void 0; return resolveSyntheticLocalProviderAuth(params, (config) => config === params.cfg ? direct : config === runtimeConfig ? runtimeAuth : void 0); } function resolveSyntheticLocalProviderAuth(params, resolveFromConfig) { const syntheticProviderAuth = params.allowPluginSyntheticAuth === false ? {} : resolveProviderSyntheticRuntimeAuth(params, resolveFromConfig); if (syntheticProviderAuth.auth) return syntheticProviderAuth.auth; if (syntheticProviderAuth.blockedOnManagedSecretRef) return null; if (hasSyntheticLocalProviderAuthConfig(params)) return { apiKey: CUSTOM_LOCAL_AUTH_MARKER, source: `models.providers.${params.provider} (synthetic local key)`, mode: "api-key" }; return null; } //#endregion //#region src/agents/model-auth-provider.ts /** * Ordered credential resolution for one provider request. */ const log = createSubsystemLogger("model-auth"); function assertAuthProfileNotRetired(params) { if (!params.deprecatedProfileIds.has(params.profileId)) return; throw new Error(`Auth profile "${params.profileId}" is retired. Run ${formatCliCommand("openclaw doctor --fix")}.`); } function shouldDeferSyntheticProfileAuth(params) { const providerConfig = resolveProviderConfig(params.cfg, params.provider); return shouldDeferProviderSyntheticProfileAuthWithPlugin({ provider: params.provider, config: params.cfg, modelApi: params.modelApi, context: { config: params.cfg, provider: params.provider, providerConfig, resolvedApiKey: params.resolvedApiKey } }) === true; } function resolveScopedAuthProfileStore(params) { return ensureAuthProfileStore(params.agentDir, { profileId: params.profileId, externalCli: externalCliDiscoveryForProviderAuth(params) }); } function assertProviderAuthReady(params) { assertAuthProfileMigrationReady(params.agentDir); assertRuntimeProviderSecretOwnerAvailable({ cfg: params.cfg, provider: params.provider }); } /** Resolves a stored provider-entry binding without general credential discovery. */ async function resolveProviderEntryApiKeyAuth(params) { const { provider, cfg } = params; assertProviderAuthReady(params); const reference = resolveProviderEntryApiKeyProfileReference(params); if (!("profileId" in reference)) return; assertAuthProfileNotRetired({ profileId: reference.profileId, deprecatedProfileIds: new Set(resolveProviderDeprecatedAuthProfileIds({ provider, config: cfg })) }); const binding = await resolveProviderEntryApiKeyBinding(params); if (binding.kind === "profile-resolved") { assertAuthModeAllowedForModel({ provider, modelApi: params.modelApi, profileId: binding.auth.profileId ?? provider, mode: binding.auth.mode }); return binding.auth; } if (binding.kind === "profile-incompatible") { const reason = binding.reason === "credential-class" ? "which is not a bearer-style auth class" : "which is not compatible with this provider entry's auth binding"; const action = binding.reason === "credential-class" ? "Use an api-key or token profile, or set apiKey to a literal bearer token." : "Use a compatible provider auth alias, configure the referenced provider entry with the same baseUrl, or set apiKey to a literal bearer token."; throw new Error(`Per-entry apiKey "${binding.profileId}" for provider "${provider}" references a "${binding.credentialType}" credential for provider "${binding.credentialProvider}", ${reason}. ${action}`); } if (binding.kind === "profile-unresolved") { const cause = binding.error ? formatErrorMessage(binding.error) : "credential resolution returned no key"; throw new Error(`Per-entry apiKey "${binding.profileId}" for provider "${provider}" matched a stored profile but failed to resolve: ${cause}. Fix the referenced profile or set apiKey to a literal bearer token.`); } } /** Resolves the credential that should be used for one provider request. */ async function resolveApiKeyForProviderCore(params) { const { provider, cfg, profileId, preferredProfile } = params; let deprecatedProfileIds; const getDeprecatedProfileIds = () => deprecatedProfileIds ??= new Set(resolveProviderDeprecatedAuthProfileIds({ provider, config: cfg })); const agentDir = params.agentDir?.trim() || (cfg ? resolveDefaultAgentDir(cfg) : void 0); assertProviderAuthReady({ cfg, provider, agentDir }); let scopedStore = params.store; const getScopedStore = (requestedProfileId) => scopedStore ??= resolveScopedAuthProfileStore({ agentDir, cfg, provider, profileId: requestedProfileId, preferredProfile }); if (profileId) { const awsSdkProfileAuth = resolveConfiguredAwsSdkProfileAuth({ cfg, provider, profileId }); if (awsSdkProfileAuth) return awsSdkProfileAuth; const store = getScopedStore(profileId); assertAuthProfileNotRetired({ profileId, deprecatedProfileIds: getDeprecatedProfileIds() }); const configuredProfileType = store.profiles[profileId]?.type; if (configuredProfileType) assertAuthModeAllowedForModel({ provider, modelApi: params.modelApi, profileId, mode: profileTypeToAuthMode(configuredProfileType) }); const resolved = await resolveApiKeyForProfile({ cfg, store, profileId, agentDir, forceRefresh: params.forceRefresh }); if (!resolved) throw new Error(`No credentials found for profile "${profileId}".`); const resolvedProfileId = resolved.profileId ?? profileId; const mode = resolved.profileType ?? store.profiles[resolvedProfileId]?.type; const result = { apiKey: sentinelizeSecretRefProfileApiKey({ apiKey: resolved.apiKey, enabled: params.secretSentinels, profileId: resolvedProfileId, provider, store }), profileId: resolvedProfileId, source: `profile:${resolvedProfileId}`, mode: mode ? profileTypeToAuthMode(mode) : "api-key" }; assertAuthModeAllowedForModel({ provider, modelApi: params.modelApi, profileId: resolvedProfileId, mode: result.mode }); if (!params.lockedProfile && shouldDeferSyntheticProfileAuth({ cfg, provider, resolvedApiKey: resolved.apiKey, modelApi: params.modelApi })) return resolveApiKeyForProviderCore({ ...params, store, profileId: void 0, lockedProfile: true }).catch(() => result); return result; } if (params.allowAuthProfileFallback !== false && (cfg?.auth?.profiles || cfg?.auth?.order)) { const store = getScopedStore(); const configuredProfileOrder = resolveAuthProfileOrder({ cfg, store, provider, preferredProfile, forModel: params.modelId }); for (const candidate of configuredProfileOrder) { const awsSdkProfileAuth = resolveConfiguredAwsSdkProfileAuth({ cfg, provider, profileId: candidate }); if (awsSdkProfileAuth) return awsSdkProfileAuth; } } if (resolveProviderAuthOverride(cfg, provider) === "aws-sdk") return resolveAwsSdkAuthInfo(); if (shouldUseImplicitAwsSdkAuth({ cfg, provider, modelApi: params.modelApi })) return resolveAwsSdkAuthInfo(); if (params.credentialPrecedence === "env-first") { const envResolved = resolveConfigAwareEnvApiKey(cfg, provider, params.workspaceDir, params.skipSetupProviderFallback); if (envResolved) { const resolvedMode = resolveDirectProviderCredentialMode({ cfg, provider, inferredMode: envResolved.source.includes("OAUTH_TOKEN") ? "oauth" : "api-key" }); if (resolvedMode === "api-key") { const inlineStore = getScopedStore(); if (isConfigBackedInlineProviderApiKey({ cfg, provider, source: envResolved.source, store: inlineStore })) assertInlineProviderApiKeyUsable({ store: inlineStore, provider }); } if (!isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: resolvedMode })) return resolveApiKeyForProviderCore({ ...params, credentialPrecedence: "profile-first" }); return { apiKey: sentinelizeConfigSecretRefEnvApiKey({ apiKey: envResolved.apiKey, source: envResolved.source, cfg, provider, enabled: params.secretSentinels }), source: envResolved.source, mode: resolvedMode }; } } const providerEntryAuth = await resolveProviderEntryApiKeyAuth({ cfg, provider, store: getScopedStore(), agentDir, modelApi: params.modelApi, secretSentinels: params.secretSentinels }); if (providerEntryAuth) return providerEntryAuth; if (shouldPreferExplicitConfigApiKeyAuth(cfg, provider)) { const runtimeCustomKey = resolveManagedSecretRefRuntimeProviderAuth({ cfg, provider, secretSentinels: params.secretSentinels }); if (runtimeCustomKey) { assertInlineProviderApiKeyUsable({ store: getScopedStore(), provider }); return runtimeCustomKey; } const customKey = resolveUsableCustomProviderApiKey({ cfg, provider, secretSentinels: params.secretSentinels }); if (customKey) { assertInlineProviderApiKeyUsable({ store: getScopedStore(), provider }); return { apiKey: customKey.apiKey, source: customKey.source, mode: "api-key" }; } } const providerConfig = resolveProviderConfig(cfg, provider); const configuredLocalKey = resolveUsableCustomProviderApiKey({ cfg, provider, secretSentinels: params.secretSentinels }); if (configuredLocalKey && isNonSecretApiKeyMarker(configuredLocalKey.apiKey)) return { apiKey: configuredLocalKey.apiKey, source: configuredLocalKey.source, mode: "api-key" }; const localMarkerEnv = resolveConfigAwareEnvApiKey(cfg, provider, params.workspaceDir, params.skipSetupProviderFallback); if (localMarkerEnv && isNonSecretApiKeyMarker(localMarkerEnv.apiKey)) return { apiKey: localMarkerEnv.apiKey, source: localMarkerEnv.source, mode: "api-key" }; const store = getScopedStore(); const order = params.allowAuthProfileFallback === false ? [] : resolveAuthProfileOrder({ cfg, store, provider, preferredProfile, forModel: params.modelId }); let deferredAuthProfileResult = null; let refreshFailure; for (const candidate of order) { const candidateType = store.profiles[candidate]?.type; const candidateMode = candidateType ? profileTypeToAuthMode(candidateType) : void 0; if (candidateMode && !isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: candidateMode })) continue; if (getDeprecatedProfileIds().has(candidate)) continue; try { const awsSdkProfileAuth = resolveConfiguredAwsSdkProfileAuth({ cfg, provider, profileId: candidate }); if (awsSdkProfileAuth) return awsSdkProfileAuth; const resolved = await resolveApiKeyForProfile({ cfg, store, profileId: candidate, agentDir, forceRefresh: params.forceRefresh }); if (resolved) { const resolvedProfileId = resolved.profileId ?? candidate; const mode = resolved.profileType ?? store.profiles[resolvedProfileId]?.type; const resolvedMode = mode ? profileTypeToAuthMode(mode) : "api-key"; const result = { apiKey: sentinelizeSecretRefProfileApiKey({ apiKey: resolved.apiKey, enabled: params.secretSentinels, profileId: resolvedProfileId, provider, store }), profileId: resolvedProfileId, source: `profile:${resolvedProfileId}`, mode: resolvedMode }; if (!isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: result.mode })) continue; if (shouldDeferSyntheticProfileAuth({ cfg, provider, resolvedApiKey: resolved.apiKey, modelApi: params.modelApi })) { deferredAuthProfileResult ??= result; continue; } return result; } } catch (err) { if (err instanceof SecretSurfaceUnavailableError) throw err; if (!refreshFailure && err instanceof OAuthRefreshFailureError && (!candidateMode || isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: candidateMode }))) refreshFailure = err; log.debug?.(`auth profile "${candidate}" failed for provider "${provider}": ${String(err)}`); } } if (refreshFailure) throw refreshFailure; const envResolved = resolveConfigAwareEnvApiKey(cfg, provider, params.workspaceDir, params.skipSetupProviderFallback); if (envResolved) { const resolvedMode = resolveDirectProviderCredentialMode({ cfg, provider, inferredMode: envResolved.source.includes("OAUTH_TOKEN") ? "oauth" : "api-key" }); if (resolvedMode === "api-key") { const inlineStore = getScopedStore(); if (isConfigBackedInlineProviderApiKey({ cfg, provider, source: envResolved.source, store: inlineStore })) assertInlineProviderApiKeyUsable({ store: inlineStore, provider }); } if (isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: resolvedMode })) return { apiKey: sentinelizeConfigSecretRefEnvApiKey({ apiKey: envResolved.apiKey, source: envResolved.source, cfg, provider, enabled: params.secretSentinels }), source: envResolved.source, mode: resolvedMode }; } const managedRuntimeAuth = resolveManagedSecretRefRuntimeProviderAuth({ cfg, provider, secretSentinels: params.secretSentinels }); if (managedRuntimeAuth && isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode: managedRuntimeAuth.mode })) { const inlineStore = getScopedStore(); if (isConfigBackedInlineProviderApiKey({ cfg, provider, source: managedRuntimeAuth.source, store: inlineStore })) assertInlineProviderApiKeyUsable({ store: inlineStore, provider }); return managedRuntimeAuth; } const customKey = resolveUsableCustomProviderApiKey({ cfg, provider, secretSentinels: params.secretSentinels }); if (customKey) { const mode = resolveDirectProviderCredentialMode({ cfg, provider, inferredMode: "api-key" }); if (isAuthModeAllowedForModel({ provider, modelApi: params.modelApi, mode })) { assertInlineProviderApiKeyUsable({ store: getScopedStore(), provider }); return { apiKey: customKey.apiKey, source: customKey.source, mode }; } } if (deferredAuthProfileResult) return deferredAuthProfileResult; const syntheticLocalAuth = await prepareSyntheticLocalProviderAuth({ cfg, provider, modelApi: params.modelApi, workspaceDir: params.workspaceDir, secretSentinels: params.secretSentinels, allowPluginSyntheticAuth: params.allowAuthProfileFallback !== false }); if (syntheticLocalAuth) return syntheticLocalAuth; const hasInlineConfiguredModels = Array.isArray(providerConfig?.models) && providerConfig.models.length > 0; if ((params.allowAuthProfileFallback !== false && !hasInlineConfiguredModels ? resolveOwningPluginIdsForProviderRef({ provider, config: cfg }) : void 0)?.length) { const pluginMissingAuthMessage = buildProviderMissingAuthMessageWithPlugin({ provider, config: cfg, context: { config: cfg, agentDir, env: process.env, provider, listProfileIds: (providerId) => listProfilesForProvider(store, providerId) } }); if (pluginMissingAuthMessage) throw new ProviderAuthError("missing-provider-auth", provider, pluginMissingAuthMessage, { providerGuidance: true }); } const authStorePath = resolveAuthStorePathForDisplay(agentDir); const agentDirContext = agentDir ? ` (agentDir: ${resolveUserPath(agentDir)})` : ""; throw new ProviderAuthError("missing-provider-auth", provider, [ `No API key found for provider "${provider}".`, `Auth store: ${authStorePath}${agentDirContext}.`, `Configure an API key (${formatCliCommand(`openclaw models auth paste-api-key --provider ${provider}`)}; add --agent <id> for a non-default agent) or copy only portable static auth profiles from the main agentDir.` ].join(" ")); } //#endregion export { hasRuntimeAvailableProviderAuth as a, isAuthModeAllowedForModel as c, createRuntimeProviderAuthLookup as i, resolveProviderEntryApiKeyAuth as n, prepareRuntimeAvailableProviderAuth as o, resolveScopedAuthProfileStore as r, prepareSyntheticLocalProviderAuth as s, resolveApiKeyForProviderCore as t };