UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

774 lines (773 loc) 40.4 kB
import { t as hasNonEmptyString } from "./string-coerce-CIXf7egm.js"; import { i as normalizeProviderIdForAuth, n as findNormalizedProviderValue, r as normalizeProviderId } from "./provider-id-DMd-TDFp.js"; import { s as coerceSecretRef } from "./types.secrets-kC0nOetj.js"; import { l as isValidSecretRef } from "./ref-contract-D92DqQ-r.js"; import { r as resolveMergedModelProviderConfig } from "./model-provider-config-DX4Bzd5F.js"; import { l as normalizePluginsConfig } from "./config-state-BkU1frVq.js"; import { i as passesManifestOwnerBasePolicy } from "./manifest-owner-policy-D98oU3cV.js"; import { t as splitTrailingAuthProfile } from "./model-ref-profile-BIKs-96s.js"; import { a as resolveAgentModelPrimaryValue } from "./model-input-BuGMCNOz.js"; import { r as modelMatchesProviderModelRoute } from "./provider-model-route-zfHlXKpI.js"; import { d as selectProviderModelAuthSources, f as buildProviderModelAuthDirectSource, g as toProviderModelAuthReadiness, h as fromProviderModelAuthReadiness, l as resolveProviderModelRouteAuthRequirement, o as selectOpenAIModelRouteAuth, p as buildProviderModelAuthSourcePlan, r as resolveConfiguredOpenAIAuthMode, t as createOpenAIModelRoutesResolver } from "./openai-model-routes-Bte2KVl5.js"; import { g as getRuntimeExternalCliProfileIds } from "./persisted-B_qhhBlh.js"; import { r as hasUsableOAuthCredential } from "./credential-state-N1MIGw99.js"; import { a as listExternalCliSyncProviderIds, s as resolveExternalCliAuthProfiles } from "./external-auth-D5zyqyNH.js"; import { c as getRuntimeAuthProfileStoreSnapshotCore } from "./runtime-snapshots-CHAErv1O.js"; import { c as resolveProfileUnusableUntil, i as isAuthCooldownBypassedForProvider, o as isProfileInCooldown, r as isActiveUnusableWindow } from "./usage-state-CAKmPrwS.js"; import { i as resolveAuthProfileEligibility, o as resolveAuthProfileOrderWithMetadata, r as prependAuthProfilePin, t as isConfiguredAwsSdkAuthProfileForProvider } from "./order-CC2RBzI5.js"; import { g as resolveProviderEnvAuthLookupMaps, h as listProviderEnvAuthLookupKeys, u as isSecretRefHeaderValueMarker } from "./model-auth-markers-jBKQn38x.js"; import { r as resolveProviderEnvAuthEvidence } from "./model-auth-env-Dq9W4xg9.js"; import { s as resolveCliRuntimeExecutionProvider } from "./model-runtime-aliases-BJ2qM8I_.js"; import { n as resolveSecretRefReadOnlyAvailability, r as resolveStoredCredentialReadOnlyAvailability, t as hasMalformedSecretInputSyntax } from "./read-only-availability-B6QkpQJd.js"; import { T as shouldPreferExplicitConfigApiKeyAuth, a as hasSyntheticLocalProviderAuthConfig, b as resolveProviderEntryApiKeyProfileReference, o as hasUsableCustomProviderApiKey, v as resolveProviderConfigSecretInput } from "./model-auth-provider-config-C_kr_q2g.js"; import { n as resolveManagedSecretRefRuntimeProviderAuth } from "./model-auth-runtime-config-DpvTPuUl.js"; import { t as resolveBundledCliBackendAuthPolicy } from "./cli-backend-auth-policy-BJQR9lNK.js"; //#region src/agents/model-auth-availability.ts /** Read-only provider/model auth availability with provider-route selection. */ const OPENAI_PROVIDER_ID = "openai"; const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses"; const EXTERNAL_CLI_REFRESH_PROVIDER_IDS = new Set(listExternalCliSyncProviderIds().map(normalizeProviderIdForAuth)); function applyCliRuntimeModelAuthAvailability(params) { if (params.evaluation.routeResolution !== null || normalizeProviderId(params.provider) === "openai") return params.evaluation; const selectedProfileId = params.pinnedProfileId?.trim() || params.preferredProfileId?.trim(); const runtimeProvider = resolveCliRuntimeExecutionProvider({ provider: params.provider, cfg: params.cfg, agentId: params.agentId, modelId: params.modelId, authProfileId: selectedProfileId, metadataSnapshot: params.metadataSnapshot }) ?? normalizeProviderId(params.provider); const runtimeOwners = params.metadataSnapshot?.owners?.cliBackends.get(normalizeProviderId(runtimeProvider)); if (runtimeOwners?.length) { const normalizedPluginConfig = normalizePluginsConfig(params.cfg.plugins); if (!runtimeOwners.some((pluginId) => passesManifestOwnerBasePolicy({ plugin: { id: pluginId }, normalizedConfig: normalizedPluginConfig }))) return { ...params.evaluation, availability: false, unavailableReason: "missing-auth", unavailableUntil: void 0 }; } const authPolicy = resolveBundledCliBackendAuthPolicy(runtimeProvider); if (selectedProfileId && authPolicy?.strictSelectedProfile && !authPolicy.nativeAuthProfileIds?.includes(selectedProfileId)) return params.pinnedProfileId ? params.authResolver.evaluateModelAuth(params.provider, { modelId: params.modelId, requiredProfileId: selectedProfileId }) : params.evaluation; if (normalizeProviderId(runtimeProvider) === normalizeProviderId(params.provider)) return params.evaluation; const runtimeAuthMode = params.authResolver.resolvePreparedRuntimeAuthMode(runtimeProvider); return runtimeAuthMode ? { availability: true, routeResolution: null, selectedAuthMode: runtimeAuthMode, evidence: "runtime" } : params.authResolver.preparedSyntheticAuthComplete ? { availability: false, routeResolution: null, unavailableReason: "missing-auth" } : { availability: void 0, routeResolution: null }; } function modeAllowed(provider, target, mode) { const requirement = resolveProviderModelRouteAuthRequirement(mode); return target.authRequirement ? requirement === target.authRequirement : provider !== OPENAI_PROVIDER_ID || target.api === void 0 || target.api === OPENAI_CODEX_RESPONSES_API || requirement === "api-key"; } function normalizeModelIdForProvider(provider, modelId) { const trimmed = splitTrailingAuthProfile(modelId).model.trim(); if (!trimmed) return; const slash = trimmed.indexOf("/"); if (slash <= 0) return trimmed; return normalizeProviderIdForAuth(trimmed.slice(0, slash)) === provider ? trimmed.slice(slash + 1).trim() || void 0 : void 0; } /** Builds one snapshot-scoped read-only auth evaluator. */ function createModelAuthAvailabilityResolver(params) { const env = params.env ?? process.env; const now = Date.now(); const isExternalCliProvider = (provider) => EXTERNAL_CLI_REFRESH_PROVIDER_IDS.has(normalizeProviderIdForAuth(provider)); const externalCliProviderIds = (params.externalCliProviderIds ?? []).filter(isExternalCliProvider); const external = externalCliProviderIds.length ? resolveExternalCliAuthProfiles(params.authStore, { allowKeychainPrompt: false, providerIds: externalCliProviderIds }) : []; const store = external.length ? { ...params.authStore, profiles: { ...params.authStore.profiles, ...Object.fromEntries(external.map((item) => [item.profileId, item.credential])) } } : params.authStore; const runtimeStore = params.preparedRuntimeAuthStore ?? (params.allowPreparedRuntimeAuth !== false ? getRuntimeAuthProfileStoreSnapshotCore(params.agentDir) : void 0); const hydratedProfileIds = /* @__PURE__ */ new Set(); const sameSecretRef = (left, right) => left !== null && right !== null && left.source === right.source && left.provider === right.provider && left.id === right.id; const runtimeCredentialOverlay = (profileId, credential) => { const runtime = runtimeStore?.profiles[profileId]; if (!runtime || credential.type !== runtime.type || credential.provider !== runtime.provider) return credential; if (credential.type === "oauth" && runtime.type === "oauth" && credential.oauthRef && !hasNonEmptyString(credential.access) && !hasNonEmptyString(credential.refresh) && hasUsableOAuthCredential(runtime, { now })) return runtime; if (credential.type === "api_key" && runtime.type === "api_key" && sameSecretRef(coerceSecretRef(credential.keyRef ?? credential.key, params.cfg.secrets?.defaults), coerceSecretRef(runtime.keyRef, params.cfg.secrets?.defaults)) && hasNonEmptyString(runtime.key)) { hydratedProfileIds.add(profileId); return { ...credential, key: runtime.key }; } if (credential.type === "token" && runtime.type === "token" && sameSecretRef(coerceSecretRef(credential.tokenRef ?? credential.token, params.cfg.secrets?.defaults), coerceSecretRef(runtime.tokenRef, params.cfg.secrets?.defaults)) && hasNonEmptyString(runtime.token)) { hydratedProfileIds.add(profileId); return { ...credential, token: runtime.token }; } return credential; }; const orderProfiles = runtimeStore ? Object.fromEntries(Object.entries(store.profiles).map(([profileId, credential]) => [profileId, runtimeCredentialOverlay(profileId, credential)])) : store.profiles; const orderBaseStore = orderProfiles === store.profiles ? store : { ...store, profiles: orderProfiles }; const orderStore = orderBaseStore.usageStats ? { ...orderBaseStore, usageStats: Object.fromEntries(Object.entries(orderBaseStore.usageStats).map(([id, stats]) => [id, { ...stats }])) } : orderBaseStore; const { aliasMap, envCandidateMap, authEvidenceMap } = resolveProviderEnvAuthLookupMaps({ config: params.cfg, workspaceDir: params.workspaceDir, env, metadataSnapshot: params.metadataSnapshot }); const synthetic = new Set((params.syntheticAuthProviderRefs ?? []).map(normalizeProviderIdForAuth)); if (resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model)?.split("/", 1)[0] === "codex") synthetic.add("codex"); const resolveRoutes = (params.routeResolverFactory ?? createOpenAIModelRoutesResolver)({ config: params.cfg, env }); const envCache = /* @__PURE__ */ new Map(); const orderCache = /* @__PURE__ */ new Map(); const normalizeProvider = (provider) => { const normalized = normalizeProviderIdForAuth(provider); return aliasMap[normalized] ?? normalized; }; const externalCliRefreshProfileIds = /* @__PURE__ */ new Set([...external.map((profile) => profile.profileId), ...getRuntimeExternalCliProfileIds(runtimeStore ?? store)]); const readOnlyAuthConfig = params.cfg; const providerInput = (provider) => resolveProviderConfigSecretInput(params.cfg, provider); const prepareAuthTarget = (provider, ref) => { const { providerConfig: configured } = providerInput(provider); const configuredModelId = ref.modelId ? normalizeModelIdForProvider(provider, ref.modelId) : void 0; const configuredModel = configuredModelId ? configured?.models?.find((model) => normalizeModelIdForProvider(provider, model.id) === configuredModelId) : void 0; return { ...ref, api: ref.api ?? configuredModel?.api ?? configured?.api, baseUrl: ref.baseUrl ?? configuredModel?.baseUrl ?? configured?.baseUrl }; }; const providerBinding = (provider) => resolveProviderEntryApiKeyProfileReference({ cfg: params.cfg, provider, store }); const envAuth = (provider) => { const normalized = normalizeProvider(provider); if (!envCache.has(normalized)) envCache.set(normalized, resolveProviderEnvAuthEvidence(normalized, env, { aliasMap, candidateMap: envCandidateMap, authEvidenceMap, config: params.cfg, workspaceDir: params.workspaceDir })); return envCache.get(normalized); }; const profileOrder = (provider, forModel, preferredProfileId, pinnedProfileId) => { const normalized = normalizeProvider(provider); const cacheKey = `${normalized}\u0000${forModel ?? ""}\u0000${preferredProfileId ?? ""}\u0000${pinnedProfileId ?? ""}`; const cached = orderCache.get(cacheKey); if (cached) return cached; const resolution = prependAuthProfilePin(resolveAuthProfileOrderWithMetadata({ cfg: readOnlyAuthConfig, store: orderStore, provider: normalized, preferredProfile: preferredProfileId, forModel, readinessMode: "read-only" }), pinnedProfileId); orderCache.set(cacheKey, resolution); return resolution; }; const profileMode = (profileId) => store.profiles[profileId]?.type ?? params.cfg.auth?.profiles?.[profileId]?.mode; const profileCredential = (profileId, credential = store.profiles[profileId]) => { return credential ? runtimeCredentialOverlay(profileId, credential) : void 0; }; const profileEligibleForReadOnlyAvailability = (provider, profileId, credential) => { const effectiveStore = store.profiles[profileId] === credential ? store : { ...store, profiles: { ...store.profiles, [profileId]: credential } }; const eligibility = resolveAuthProfileEligibility({ cfg: readOnlyAuthConfig, store: effectiveStore, provider: normalizeProvider(provider), profileId, now }); return eligibility.eligible || eligibility.reasonCode === "unresolved_ref"; }; const invalidProfilePin = (provider, ref) => { const profileId = ref.pinnedProfileId?.trim() || void 0; return profileId !== void 0 && !resolveAuthProfileEligibility({ cfg: readOnlyAuthConfig, store: orderStore, provider: normalizeProvider(provider), profileId, now }).eligible; }; const credentialAvailability = (provider, profileId, credential, target) => { if (!modeAllowed(provider, target, credential.type)) return false; return resolveStoredCredentialReadOnlyAvailability({ credential, cfg: params.cfg, env, now, canRefreshOAuth: provider === OPENAI_PROVIDER_ID || externalCliRefreshProfileIds.has(profileId) }); }; const resolvedProfileAvailability = (provider, profileId, credential, target) => { if (!hydratedProfileIds.has(profileId)) return credentialAvailability(provider, profileId, credential, target); if (!modeAllowed(provider, target, credential.type)) return false; return credential.type !== "token" || credential.expires === void 0 || credential.expires > now; }; const profileInCooldown = (profileId, target) => { const cooldownModel = target.modelId ? splitTrailingAuthProfile(target.modelId).model : void 0; return isProfileInCooldown(store, profileId, now, cooldownModel); }; const hasPermanentAuthFailure = (stats) => stats?.disabledReason === "auth_permanent" && isActiveUnusableWindow(stats.disabledUntil, now); const profileAvailability = (provider, profileId, target, allowCooldown = false) => { if (!allowCooldown && profileInCooldown(profileId, target)) return false; if (isConfiguredAwsSdkAuthProfileForProvider({ cfg: params.cfg, provider, profileId })) return modeAllowed(provider, target, "aws-sdk"); const credential = profileCredential(profileId); if (!credential || !profileEligibleForReadOnlyAvailability(provider, profileId, credential)) return false; return resolvedProfileAvailability(provider, profileId, credential, target); }; const hasProfileEvidence = (provider) => { const normalized = normalizeProvider(provider); if (findNormalizedProviderValue(params.cfg.auth?.order, normalized) !== void 0) return true; if (Object.values(params.cfg.auth?.profiles ?? {}).some((profile) => normalizeProvider(profile.provider) === normalized)) return true; return Object.keys(store.profiles).some((profileId) => { const reason = resolveAuthProfileEligibility({ cfg: params.cfg, store, provider: normalized, profileId }).reasonCode; return reason !== "provider_mismatch" && reason !== "profile_missing"; }); }; const firstProfileEvidenceId = (provider) => { const normalized = normalizeProvider(provider); const configuredOrder = findNormalizedProviderValue(params.cfg.auth?.order, normalized); const storedOrder = findNormalizedProviderValue(store.order, normalized); return (configuredOrder ?? storedOrder ?? Object.keys(store.profiles)).find((profileId) => { const reason = resolveAuthProfileEligibility({ cfg: params.cfg, store, provider: normalized, profileId }).reasonCode; return reason !== "provider_mismatch" && reason !== "profile_missing"; }); }; const unprofiledEvaluation = (provider, target) => { const { providerConfig: configured, ref: apiKeyRef } = providerInput(provider); const configuredAuth = target.pinnedProfileId ? void 0 : configured?.auth; if (configuredAuth === "aws-sdk") return { availability: modeAllowed(provider, target, "aws-sdk"), selectedAuthMode: "aws-sdk", evidence: "aws-sdk" }; const apiKey = target.pinnedProfileId && !apiKeyRef ? void 0 : configured?.apiKey; const configuredBearerMode = configuredAuth === "api-key" || configuredAuth === "oauth" || configuredAuth === "token" ? configuredAuth : "api-key"; if (!apiKeyRef && hasMalformedSecretInputSyntax(apiKey)) return { availability: false, evidence: "provider-config" }; const binding = target.pinnedProfileId ? { kind: "none" } : providerBinding(provider); if (binding.kind === "profile") { const credential = profileCredential(binding.profileId, binding.credential); const cooldownModel = target.modelId ? splitTrailingAuthProfile(target.modelId).model : void 0; return { availability: credential && !isProfileInCooldown(store, binding.profileId, now, cooldownModel) && profileEligibleForReadOnlyAvailability(binding.credential.provider, binding.profileId, credential) ? resolvedProfileAvailability(provider, binding.profileId, credential, target) : false, selectedProfileId: binding.profileId, selectedAuthMode: credential?.type ?? binding.credential.type, evidence: "profile" }; } if (binding.kind === "profile-incompatible") return { availability: false, evidence: "profile" }; const inlineUsageStats = isAuthCooldownBypassedForProvider(provider) ? void 0 : store.usageStats?.[`inline-api-key:${normalizeProviderId(provider)}`]; const inlineKeyUnusableUntil = inlineUsageStats ? resolveProfileUnusableUntil(inlineUsageStats) : null; if (inlineKeyUnusableUntil != null && inlineKeyUnusableUntil > now) return { availability: false, evidence: "provider-config", ...hasPermanentAuthFailure(inlineUsageStats) ? { unavailableReason: "auth-failed" } : { unavailableReason: "cooldown", unavailableUntil: inlineKeyUnusableUntil } }; if (binding.kind === "literal") return { availability: modeAllowed(provider, target, configuredBearerMode), selectedAuthMode: configuredBearerMode, evidence: "provider-config" }; if (binding.kind === "marker") { if (binding.evidence === "environment" && typeof apiKey === "string") return { availability: modeAllowed(provider, target, configuredBearerMode) ? hasNonEmptyString(env[apiKey.trim()]) : false, selectedAuthMode: configuredBearerMode, evidence: "environment" }; if (!modeAllowed(provider, target, configuredBearerMode)) return { availability: false, selectedAuthMode: configuredBearerMode, evidence: binding.evidence }; if (hasUsableCustomProviderApiKey(params.cfg, provider, env)) return { availability: true, selectedAuthMode: configuredBearerMode, evidence: binding.evidence }; const managed = typeof apiKey === "string" && isSecretRefHeaderValueMarker(apiKey); return { availability: managed ? Boolean(resolveManagedSecretRefRuntimeProviderAuth({ provider, cfg: params.cfg })) || void 0 : void 0, selectedAuthMode: configuredBearerMode, evidence: managed ? "runtime" : binding.evidence }; } if (apiKeyRef) { if (!isValidSecretRef(apiKeyRef) || !modeAllowed(provider, target, configuredBearerMode)) return { availability: false, selectedAuthMode: configuredBearerMode, evidence: "provider-config" }; const available = resolveSecretRefReadOnlyAvailability(apiKeyRef, params.cfg, env); const runtimeAvailable = Boolean(resolveManagedSecretRefRuntimeProviderAuth({ provider, cfg: params.cfg })); return { availability: runtimeAvailable ? true : available, selectedAuthMode: configuredBearerMode, evidence: runtimeAvailable ? "runtime" : "provider-config" }; } if (apiKey !== void 0 && !(typeof apiKey === "string" && apiKey.trim() === "")) return { availability: false, evidence: "provider-config" }; if (provider === "amazon-bedrock" && (target.api === void 0 || target.api === "bedrock-converse-stream") && configured?.auth === void 0 && apiKey === void 0) return { availability: modeAllowed(provider, target, "aws-sdk"), selectedAuthMode: "aws-sdk", evidence: "aws-sdk" }; const preparedRuntimeAuthMode = params.preparedRuntimeAuthModes?.[normalizeProviderIdForAuth(provider)] ?? params.preparedRuntimeAuthModes?.[normalizeProvider(provider)]; if (preparedRuntimeAuthMode) return { availability: modeAllowed(provider, target, preparedRuntimeAuthMode), selectedAuthMode: preparedRuntimeAuthMode, evidence: "runtime" }; const environment = envAuth(provider); if (environment) { if (provider === "amazon-bedrock" && environment.mode === "aws-sdk") return { availability: modeAllowed(provider, target, "aws-sdk"), selectedAuthMode: "aws-sdk", evidence: "aws-sdk" }; const mode = configured?.auth ?? environment.mode; return { availability: modeAllowed(provider, target, mode), selectedAuthMode: mode, evidence: "environment" }; } const hasCompatibleCodexSyntheticAuth = provider === OPENAI_PROVIDER_ID && synthetic.has("codex") && (target.authRequirement === "subscription" || target.api === OPENAI_CODEX_RESPONSES_API); const hasDeclaredSyntheticAuth = synthetic.has(normalizeProviderIdForAuth(provider)) || synthetic.has(normalizeProvider(provider)); if (hasSyntheticLocalProviderAuthConfig({ cfg: params.cfg, provider, route: hasDeclaredSyntheticAuth ? target : void 0 })) return { availability: true, evidence: "synthetic" }; if (hasDeclaredSyntheticAuth || hasCompatibleCodexSyntheticAuth) return params.preparedSyntheticAuthComplete ? { availability: false, evidence: "synthetic", unavailableReason: "missing-auth" } : { availability: void 0, evidence: "synthetic" }; const hasAuthEvidence = configured?.auth !== void 0 || apiKey !== void 0 && !(typeof apiKey === "string" && apiKey.trim() === "") || hasProfileEvidence(provider); return { availability: hasAuthEvidence ? false : void 0, unavailableReason: hasAuthEvidence ? "auth-failed" : "missing-auth", selectedAuthMode: configured?.auth }; }; const automaticProfileSource = (provider, profileId, target) => ({ kind: "profile", profileId, mode: profileMode(profileId), readiness: toProviderModelAuthReadiness(profileAvailability(provider, profileId, target, true)), cooldown: profileInCooldown(profileId, target) ? "active" : "clear" }); const requiredProfileSource = (provider, profileId, target, ignoreCooldown) => ({ kind: "profile", profileId, mode: profileMode(profileId), readiness: toProviderModelAuthReadiness(profileAvailability(provider, profileId, target, ignoreCooldown)), cooldown: "clear" }); const cooldownEvaluation = (profiles, target) => { const model = target.modelId ? splitTrailingAuthProfile(target.modelId).model : void 0; const retryTimes = profiles.flatMap((profile) => { if (profile.readiness === "unavailable" || profile.cooldown !== "active") return []; const stats = store.usageStats?.[profile.profileId]; const until = stats && !hasPermanentAuthFailure(stats) ? resolveProfileUnusableUntil(stats, model) : null; return until !== null && until > now ? [until] : []; }); return { availability: false, unavailableReason: retryTimes.length ? "cooldown" : "auth-failed", ...retryTimes.length ? { unavailableUntil: Math.min(...retryTimes) } : {} }; }; const rejectedSourceEvaluation = (reason, plan, target) => reason === "all-cooldown" && plan.kind === "automatic" ? cooldownEvaluation(plan.orderedProfiles.filter((profile) => !target.authRequirement || resolveProviderModelRouteAuthRequirement(profile.mode) === target.authRequirement), target) : { availability: false, unavailableReason: "auth-failed" }; const sourceEvaluation = (selection, provider, target, directEvaluation) => { if (selection.kind === "none") return directEvaluation; const source = selection.source; if (source.kind === "profile") { const availability = selection.kind === "unavailable" ? false : fromProviderModelAuthReadiness(source.readiness); const profile = availability === false ? automaticProfileSource(provider, source.profileId, target) : void 0; return { ...availability === false ? profile && profile.readiness !== "unavailable" && profile.cooldown === "active" ? cooldownEvaluation([profile], target) : { availability, unavailableReason: "auth-failed" } : { availability }, selectedProfileId: source.profileId, selectedAuthMode: source.mode, evidence: "profile" }; } const { unavailableReason, ...evaluation } = directEvaluation; return { ...evaluation, ...source.readiness === "unavailable" ? { unavailableReason: unavailableReason ?? "auth-failed" } : {}, selectedAuthMode: source.mode }; }; const directPolicy = (provider, target) => { const { providerConfig: configured, ref: apiKeyRef } = providerInput(provider); const pinned = Boolean(target.pinnedProfileId); const configuredAuth = pinned ? void 0 : configured?.auth; const binding = pinned ? { kind: "none" } : providerBinding(provider); const markerUsable = binding.kind === "marker" && hasUsableCustomProviderApiKey(params.cfg, provider, env); const hasDirectMaterial = binding.kind === "literal" || markerUsable || apiKeyRef !== null; const required = configuredAuth === "aws-sdk" || markerUsable || apiKeyRef !== null || hasDirectMaterial && shouldPreferExplicitConfigApiKeyAuth(params.cfg, provider); const environment = envAuth(provider); const environmentMode = environment ? configuredAuth ?? environment.mode : void 0; const evaluation = !required && environmentMode ? { selectedAuthMode: environmentMode, availability: modeAllowed(provider, target, environmentMode), evidence: environmentMode === "aws-sdk" ? "aws-sdk" : "environment" } : unprofiledEvaluation(provider, target); const direct = buildProviderModelAuthDirectSource({ mode: evaluation.selectedAuthMode, availability: evaluation.availability, evidence: evaluation.evidence ?? "none", authorization: evaluation.evidence === "environment" && !hasDirectMaterial ? "ambient" : "declared" }); return { binding, direct, evaluation, hasDirectMaterial, hasDirectFallback: hasDirectMaterial || !pinned && direct.evidence !== "none", markerUsable, required }; }; const automaticSourceRejection = (provider, ref, target) => { if (ref.requiredProfileId?.trim()) return; const policy = directPolicy(provider, target); if (policy.required || policy.binding.kind === "profile" || policy.binding.kind === "profile-incompatible") return; const orderResolution = profileOrder(provider, ref.modelId, ref.preferredProfileId, ref.pinnedProfileId); const plan = buildProviderModelAuthSourcePlan({ profiles: orderResolution.profileIds.map((profileId) => automaticProfileSource(provider, profileId, target)), preferredProfileId: ref.pinnedProfileId ?? ref.preferredProfileId, explicitOrder: orderResolution.hasExplicitOrder, ...policy.hasDirectFallback ? { fallback: policy.direct } : {} }); const decision = selectProviderModelAuthSources({ provider, plan }); return decision.kind === "rejected" ? { ...rejectedSourceEvaluation(decision.reason, plan, target), evidence: "profile", ...decision.source ? { selectedAuthMode: decision.source.mode, selectedProfileId: decision.source.profileId } : {} } : void 0; }; const resolveProviderEvaluation = (rawProvider, ref = {}, preparedTarget) => { const provider = normalizeProviderIdForAuth(rawProvider); const target = preparedTarget ?? prepareAuthTarget(provider, ref); const profileLock = ref.requiredProfileId?.trim(); if (invalidProfilePin(provider, ref)) return { availability: false, unavailableReason: "auth-failed", evidence: "profile" }; const policy = directPolicy(provider, target); if (!profileLock && policy.binding.kind === "profile-incompatible") return { availability: false, unavailableReason: "auth-failed", evidence: "profile" }; const orderResolution = profileOrder(provider, ref.modelId, ref.preferredProfileId, ref.pinnedProfileId); const boundProfileId = !profileLock && policy.binding.kind === "profile" ? policy.binding.profileId : void 0; const ownership = profileLock ? { reason: "runtime-binding", source: requiredProfileSource(provider, profileLock, target, true) } : boundProfileId ? { reason: "provider-binding", source: requiredProfileSource(provider, boundProfileId, target, false) } : policy.required ? { reason: "configured-auth", source: policy.direct } : void 0; const sourcePlan = buildProviderModelAuthSourcePlan({ ...ownership ? { ownership } : {}, profiles: orderResolution.profileIds.map((profileId) => automaticProfileSource(provider, profileId, target)), preferredProfileId: ref.pinnedProfileId ?? ref.preferredProfileId, explicitOrder: orderResolution.hasExplicitOrder, ...policy.hasDirectFallback ? { fallback: policy.direct } : {} }); const decision = selectProviderModelAuthSources({ provider, plan: sourcePlan }); if (decision.kind === "rejected") return { ...rejectedSourceEvaluation(decision.reason, sourcePlan, target), ...decision.source ? { selectedProfileId: decision.source.profileId, selectedAuthMode: decision.source.mode } : {}, evidence: "profile" }; return sourceEvaluation(decision.selection, provider, target, policy.evaluation); }; const resolveProviderAuthAvailability = (provider, ref = {}) => resolveProviderEvaluation(provider, ref).availability; const evaluateModelAuth = (rawProvider, ref = {}) => { const provider = normalizeProviderIdForAuth(rawProvider); if (provider !== OPENAI_PROVIDER_ID) return { ...resolveProviderEvaluation(provider, ref), routeResolution: null }; if (invalidProfilePin(provider, ref)) return { availability: false, unavailableReason: "auth-failed", routeResolution: null }; const routeResolution = resolveRoutes(ref); if (!routeResolution) return { availability: void 0, routeResolution: null }; if (routeResolution.kind === "incompatible") return { availability: false, routeResolution }; if (routeResolution.kind === "indeterminate") return { ...automaticSourceRejection(provider, ref, prepareAuthTarget(provider, ref)) ?? { availability: void 0 }, routeResolution }; const modelLock = ref.requiredProfileId?.trim(); const configuredAuthMode = ref.pinnedProfileId ? void 0 : resolveConfiguredOpenAIAuthMode(params.cfg); const awsSdkTerminal = !modelLock && configuredAuthMode === "aws-sdk"; const baseTarget = prepareAuthTarget(provider, ref); const basePolicy = directPolicy(provider, baseTarget); if (!modelLock && !awsSdkTerminal && basePolicy.binding.kind === "profile-incompatible") return { availability: false, unavailableReason: "auth-failed", routeResolution }; const bindingProfileId = !modelLock && !awsSdkTerminal && basePolicy.binding.kind === "profile" ? basePolicy.binding.profileId : void 0; const orderResolution = profileOrder(provider, ref.modelId, ref.preferredProfileId, ref.pinnedProfileId); const materializedModelId = ref.modelId ? normalizeModelIdForProvider(provider, ref.modelId)?.toLowerCase() : void 0; const materialized = !modelLock && !ref.pinnedProfileId && !bindingProfileId && !basePolicy.required && materializedModelId ? params.preparedRuntimeAuthMaterializations?.find((fact) => (!orderResolution.hasExplicitOrder || fact.authProfileId !== void 0 && orderResolution.profileIds.includes(fact.authProfileId)) && normalizeProvider(fact.provider) === provider && fact.modelId === materializedModelId && routeResolution.routes.some((route) => { const configuredRequirement = resolveProviderModelRouteAuthRequirement(configuredAuthMode); return (!configuredRequirement || configuredRequirement === route.authRequirement) && route.runtimePolicy?.compatibleIds.some((runtimeId) => runtimeId.trim().toLowerCase() === fact.runtimeOwnerId) === true && route.api.toLowerCase() === fact.modelApi && route.requestTransportOverrides === fact.requestTransportOverrides && modelMatchesProviderModelRoute({ provider, api: fact.modelApi, baseUrl: fact.modelBaseUrl, route }) && modeAllowed(provider, { ...ref, api: route.api, baseUrl: route.baseUrl, authRequirement: route.authRequirement }, fact.authMode); })) : void 0; if (materialized) { const selectedRoute = routeResolution.routes.find((route) => route.runtimePolicy?.compatibleIds.some((runtimeId) => runtimeId.trim().toLowerCase() === materialized.runtimeOwnerId) === true && route.api.toLowerCase() === materialized.modelApi && route.requestTransportOverrides === materialized.requestTransportOverrides && modelMatchesProviderModelRoute({ provider, api: materialized.modelApi, baseUrl: materialized.modelBaseUrl, route })); if (selectedRoute) return { availability: true, routeResolution, selectedRoute, selectedAuthMode: materialized.authMode, ...materialized.authProfileId ? { selectedProfileId: materialized.authProfileId } : {}, evidence: "runtime" }; } const selectedConfiguredMode = awsSdkTerminal ? "aws-sdk" : bindingProfileId ? void 0 : configuredAuthMode ?? (basePolicy.hasDirectMaterial ? "api-key" : void 0); const automaticRouteAuthMode = basePolicy.hasDirectFallback && configuredAuthMode && !basePolicy.required ? void 0 : selectedConfiguredMode; const targetForMode = (mode) => { const requirement = resolveProviderModelRouteAuthRequirement(mode); const route = requirement ? routeResolution.routes.find((candidate) => candidate.authRequirement === requirement) : void 0; return route ? { ...ref, api: route.api, baseUrl: route.baseUrl, authRequirement: route.authRequirement } : baseTarget; }; const policy = directPolicy(provider, targetForMode(selectedConfiguredMode ?? basePolicy.direct.mode)); let profileIds = orderResolution.profileIds; if (profileIds.length === 0 && !modelLock && !bindingProfileId && !policy.required) { const evidenceProfileId = firstProfileEvidenceId(provider); if (evidenceProfileId) profileIds = [evidenceProfileId]; } const ownership = modelLock ? { reason: "runtime-binding", source: requiredProfileSource(provider, modelLock, targetForMode(profileMode(modelLock)), true) } : bindingProfileId ? { reason: "provider-binding", source: requiredProfileSource(provider, bindingProfileId, targetForMode(profileMode(bindingProfileId)), false) } : policy.required ? { reason: "configured-auth", source: policy.direct } : void 0; const sourcePlan = buildProviderModelAuthSourcePlan({ ...ownership ? { ownership } : {}, profiles: profileIds.map((profileId) => automaticProfileSource(provider, profileId, targetForMode(profileMode(profileId)))), preferredProfileId: ref.pinnedProfileId ?? ref.preferredProfileId, explicitOrder: orderResolution.hasExplicitOrder, ...policy.hasDirectFallback ? { fallback: policy.direct } : {} }); const syntheticCodexOwnsAuth = !modelLock && !ref.pinnedProfileId && !selectedConfiguredMode && (policy.binding.kind === "none" || policy.binding.kind === "marker" && !policy.markerUsable) && sourcePlan.kind === "automatic" && !sourcePlan.profiles.explicitOrder && (sourcePlan.profiles.kind === "empty" || sourcePlan.profiles.kind === "all-unavailable") && synthetic.has("codex") && routeResolution.routes.every((route) => route.runtimePolicy?.compatibleIds?.some((runtimeId) => runtimeId.trim().toLowerCase() === "codex")); const routeAuthDecision = selectOpenAIModelRouteAuth({ resolution: routeResolution, sourcePlan, configuredAuthMode: automaticRouteAuthMode, ...syntheticCodexOwnsAuth ? { runtimeAuthOwner: { id: "codex" } } : {}, ...syntheticCodexOwnsAuth && resolveMergedModelProviderConfig(params.cfg, provider) === void 0 ? { allowNativeAuthOnSingleRoute: true } : {} }); if (routeAuthDecision.kind === "deferred" && syntheticCodexOwnsAuth) return { availability: void 0, routeResolution, evidence: "synthetic" }; if (routeAuthDecision.kind !== "selected") { const rejectedSource = routeAuthDecision.kind === "rejected" ? routeAuthDecision.source : void 0; const projectRejectedSource = routeAuthDecision.kind === "rejected" && rejectedSource && (routeAuthDecision.reason === "all-cooldown" || rejectedSource.readiness === "unavailable") ? rejectedSource : void 0; const rejectedRequirement = resolveProviderModelRouteAuthRequirement(rejectedSource?.mode); const rejectedRoute = routeAuthDecision.kind === "rejected" ? routeAuthDecision.route : void 0; const rejectedSourceRoute = rejectedRequirement ? routeResolution.routes.find((candidate) => candidate.authRequirement === rejectedRequirement) : void 0; const selectedRoute = rejectedRoute ?? rejectedSourceRoute ?? (routeResolution.routes.length === 1 ? routeResolution.routes[0] : void 0); return { ...routeAuthDecision.kind === "rejected" ? rejectedSourceEvaluation(routeAuthDecision.reason, sourcePlan, { ...ref, authRequirement: rejectedRoute?.authRequirement ?? (routeResolution.routes.length === 1 ? selectedRoute?.authRequirement : void 0) }) : { availability: false }, ...sourcePlan.kind === "automatic" && sourcePlan.profiles.kind === "empty" && !sourcePlan.profiles.explicitOrder && !policy.hasDirectFallback ? { unavailableReason: policy.evaluation.unavailableReason } : {}, routeResolution, ...projectRejectedSource ? { selectedProfileId: projectRejectedSource.profileId, selectedAuthMode: projectRejectedSource.mode, evidence: "profile" } : {}, ...selectedRoute ? { selectedRoute } : {} }; } const selectedRoute = routeAuthDecision.selection.route; const evaluation = sourceEvaluation(routeAuthDecision.selection, provider, { ...ref, ...selectedRoute }, policy.evaluation); const syntheticSubscriptionRoute = routeResolution.routes.find((route) => route.authRequirement === "subscription"); if (syntheticCodexOwnsAuth && evaluation.availability !== true && synthetic.has("codex") && syntheticSubscriptionRoute) return { availability: void 0, routeResolution, evidence: "synthetic" }; return { ...evaluation, availability: evaluation.availability === void 0 && !evaluation.evidence ? false : evaluation.availability, routeResolution, selectedRoute }; }; const providerDiscoveryProviderIds = /* @__PURE__ */ new Set(); const addProviderDiscoveryProviderId = (provider) => { if (!provider) return; const normalized = normalizeProvider(provider); if (normalized) providerDiscoveryProviderIds.add(normalized); }; for (const credential of Object.values(store.profiles)) addProviderDiscoveryProviderId(credential.provider); for (const profile of Object.values(params.cfg.auth?.profiles ?? {})) addProviderDiscoveryProviderId(profile.provider); for (const provider of listProviderEnvAuthLookupKeys({ envCandidateMap, authEvidenceMap })) if (envAuth(provider)) addProviderDiscoveryProviderId(provider); for (const plugin of params.metadataSnapshot?.index?.plugins ?? []) { if (!plugin.enabled || !(plugin.syntheticAuthRefs ?? []).some((ref) => synthetic.has(normalizeProviderIdForAuth(ref)))) continue; for (const provider of [...plugin.contributions?.providers ?? [], ...plugin.contributions?.modelCatalogProviders ?? []]) addProviderDiscoveryProviderId(provider); } if (synthetic.has("codex")) addProviderDiscoveryProviderId(OPENAI_PROVIDER_ID); return { providerDiscoveryProviderIds: [...providerDiscoveryProviderIds].toSorted((left, right) => left.localeCompare(right)), preparedSyntheticAuthComplete: params.preparedSyntheticAuthComplete === true, evaluateModelAuth, resolvePreparedRuntimeAuthMode: (provider) => params.preparedRuntimeAuthModes?.[normalizeProviderIdForAuth(provider)], resolveProviderAuthAvailability, hasSyntheticAuth: (provider) => synthetic.has(normalizeProviderIdForAuth(provider)) || synthetic.has(normalizeProvider(provider)) || normalizeProviderIdForAuth(provider) === OPENAI_PROVIDER_ID && synthetic.has("codex") || hasSyntheticLocalProviderAuthConfig({ cfg: params.cfg, provider: normalizeProviderIdForAuth(provider) }) }; } //#endregion export { createModelAuthAvailabilityResolver as n, applyCliRuntimeModelAuthAvailability as t };