openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
774 lines (773 loc) • 40.4 kB
JavaScript
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 };