openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
245 lines (244 loc) • 11 kB
JavaScript
import { i as normalizeProviderId, n as findNormalizedProviderValue } from "./provider-id-Dq06Bcx6.js";
import { r as resolveProviderIdForAuth } from "./provider-auth-aliases-BNZrcvHv.js";
import { M as evaluateStoredCredentialEligibility } from "./store-C8spD0DG.js";
import { n as listProfilesForProvider, t as dedupeProfileIds } from "./profile-list-DI8_o0Rw.js";
import { o as isProfileInCooldown, s as resolveProfileUnusableUntil, t as clearExpiredCooldowns } from "./usage-state-glPP7WfI.js";
//#region src/agents/auth-profiles/order.ts
/**
* Auth profile ordering and eligibility.
* Resolves configured/stored auth order, provider aliases, cooldowns, and
* profile compatibility for provider auth selection.
*/
const OPENAI_PROVIDER_ID = "openai";
const OPENAI_CODEX_PROVIDER_ID = "openai";
function isOpenAIApiKeyCompatibleWithCodexAuth(params) {
if (params.providerAuthKey !== OPENAI_CODEX_PROVIDER_ID) return false;
const providerKey = resolveProviderIdForAuth(params.profileProvider ?? "", {
config: params.cfg,
...params.authAliasLookupParams
});
const mode = params.credential?.type ?? params.profileMode;
return providerKey === OPENAI_PROVIDER_ID && mode === "api_key";
}
function isCredentialProviderCompatibleWithAuthProvider(params) {
return resolveProviderIdForAuth(params.credential.provider, {
config: params.cfg,
...params.authAliasLookupParams
}) === params.providerAuthKey || isOpenAIApiKeyCompatibleWithCodexAuth({
cfg: params.cfg,
authAliasLookupParams: params.authAliasLookupParams,
providerAuthKey: params.providerAuthKey,
credential: params.credential,
profileProvider: params.credential.provider
});
}
/** Returns true when a stored credential can authenticate the requested provider. */
function isStoredCredentialCompatibleWithAuthProvider(params) {
return isCredentialProviderCompatibleWithAuthProvider({
cfg: params.cfg,
authAliasLookupParams: params.authAliasLookupParams,
providerAuthKey: resolveProviderIdForAuth(params.provider, {
config: params.cfg,
...params.authAliasLookupParams
}),
credential: params.credential
});
}
function isConfiguredProfileCompatibleWithAuthProvider(params) {
return resolveProviderIdForAuth(params.provider, { config: params.cfg }) === params.providerAuthKey || isOpenAIApiKeyCompatibleWithCodexAuth({
cfg: params.cfg,
providerAuthKey: params.providerAuthKey,
credential: params.credential,
profileProvider: params.provider,
profileMode: params.mode
});
}
function listProfilesCompatibleWithAuthProvider(params) {
if (params.providerAuthKey !== OPENAI_CODEX_PROVIDER_ID) return listProfilesForProvider(params.store, params.provider);
return Object.entries(params.store.profiles).filter(([, credential]) => isCredentialProviderCompatibleWithAuthProvider({
cfg: params.cfg,
providerAuthKey: params.providerAuthKey,
credential
})).map(([profileId]) => profileId);
}
function resolveProviderAuthMode(cfg, provider) {
const providers = cfg?.models?.providers;
if (!providers) return;
const auth = findNormalizedProviderValue(providers, provider)?.auth;
return typeof auth === "string" ? auth : void 0;
}
function providerAllowsAwsSdkAuth(cfg, provider) {
return resolveProviderAuthMode(cfg, provider) === "aws-sdk";
}
/** Returns true when config declares an aws-sdk auth profile for a provider. */
function isConfiguredAwsSdkAuthProfileForProvider(params) {
const profileConfig = params.cfg?.auth?.profiles?.[params.profileId];
if (!profileConfig || profileConfig.mode !== "aws-sdk") return false;
const providerAuthKey = resolveProviderIdForAuth(params.provider, { config: params.cfg });
if (resolveProviderIdForAuth(profileConfig.provider, { config: params.cfg }) !== providerAuthKey) return false;
return providerAllowsAwsSdkAuth(params.cfg, params.provider);
}
/** Resolves whether a profile can be used for a provider right now. */
function resolveAuthProfileEligibility(params) {
const providerAuthKey = resolveProviderIdForAuth(params.provider, { config: params.cfg });
const cred = params.store.profiles[params.profileId];
if (!cred) {
if (isConfiguredAwsSdkAuthProfileForProvider({
cfg: params.cfg,
provider: params.provider,
profileId: params.profileId
})) return {
eligible: true,
reasonCode: "ok"
};
return {
eligible: false,
reasonCode: "profile_missing"
};
}
if (!isCredentialProviderCompatibleWithAuthProvider({
cfg: params.cfg,
providerAuthKey,
credential: cred
})) return {
eligible: false,
reasonCode: "provider_mismatch"
};
const profileConfig = params.cfg?.auth?.profiles?.[params.profileId];
if (profileConfig) {
if (!isConfiguredProfileCompatibleWithAuthProvider({
cfg: params.cfg,
providerAuthKey,
provider: profileConfig.provider,
mode: profileConfig.mode,
credential: cred
})) return {
eligible: false,
reasonCode: "provider_mismatch"
};
if (profileConfig.mode !== cred.type) {
if (!(profileConfig.mode === "oauth" && cred.type === "token")) return {
eligible: false,
reasonCode: "mode_mismatch"
};
}
}
const credentialEligibility = evaluateStoredCredentialEligibility({
credential: cred,
now: params.now
});
return {
eligible: credentialEligibility.eligible,
reasonCode: credentialEligibility.reasonCode
};
}
/** Resolves ordered auth profile candidates for a provider. */
/** Resolve ordered usable auth profile ids for a provider. */
function resolveAuthProfileOrder(params) {
const { cfg, store, provider, preferredProfile } = params;
const providerKey = normalizeProviderId(provider);
const providerAuthKey = resolveProviderIdForAuth(provider, { config: cfg });
const now = Date.now();
clearExpiredCooldowns(store, now);
const openAIOrderAliasProvider = providerAuthKey === OPENAI_CODEX_PROVIDER_ID || providerKey === OPENAI_CODEX_PROVIDER_ID ? OPENAI_PROVIDER_ID : void 0;
const directStoredOrder = resolveAuthOrder(store.order, providerAuthKey) ?? resolveAuthOrder(store.order, providerKey);
const aliasStoredOrder = openAIOrderAliasProvider ? resolveAuthOrder(store.order, openAIOrderAliasProvider) : void 0;
const directConfiguredOrder = resolveAuthOrder(cfg?.auth?.order, providerAuthKey) ?? resolveAuthOrder(cfg?.auth?.order, providerKey);
const aliasConfiguredOrder = openAIOrderAliasProvider ? resolveAuthOrder(cfg?.auth?.order, openAIOrderAliasProvider) : void 0;
const directExplicitOrder = directStoredOrder ?? directConfiguredOrder;
const aliasExplicitOrder = aliasStoredOrder ?? aliasConfiguredOrder;
const explicitOrderFromStore = directStoredOrder !== void 0 || directExplicitOrder === void 0 && aliasStoredOrder !== void 0;
const explicitProfiles = cfg?.auth?.profiles ? Object.entries(cfg.auth.profiles).filter(([profileId, profile]) => isConfiguredProfileCompatibleWithAuthProvider({
cfg,
providerAuthKey,
provider: profile.provider,
mode: profile.mode,
credential: store.profiles[profileId]
})).map(([profileId]) => profileId) : [];
const storeProfiles = listProfilesCompatibleWithAuthProvider({
cfg,
store,
provider,
providerAuthKey
});
const nativeStoreProfiles = openAIOrderAliasProvider && providerAuthKey === OPENAI_CODEX_PROVIDER_ID ? storeProfiles.filter((profileId) => isNativeCredentialProviderCompatibleWithAuthProvider({
cfg,
providerAuthKey,
credential: store.profiles[profileId]
})) : [];
const explicitOrder = directExplicitOrder ?? (aliasExplicitOrder ? mergeAliasOrderWithNativeProfiles({
aliasOrder: aliasExplicitOrder,
nativeProfiles: nativeStoreProfiles
}) : void 0);
const baseOrder = explicitOrder ?? (explicitProfiles.length > 0 ? explicitProfiles : storeProfiles);
if (baseOrder.length === 0) return [];
const isValidProfile = (profileId) => resolveAuthProfileEligibility({
cfg,
store,
provider,
profileId,
now
}).eligible;
let filtered = baseOrder.filter(isValidProfile);
let repairedFallbackToStoreProfiles = false;
const allBaseProfilesMissing = baseOrder.every((profileId) => !store.profiles[profileId]);
if (filtered.length === 0 && allBaseProfilesMissing && (explicitOrderFromStore || explicitProfiles.length > 0)) {
filtered = storeProfiles.filter(isValidProfile);
repairedFallbackToStoreProfiles = true;
}
const deduped = dedupeProfileIds(filtered);
if (explicitOrder && explicitOrder.length > 0 && !repairedFallbackToStoreProfiles) {
const available = [];
const inCooldown = [];
for (const profileId of deduped) if (isProfileInCooldown(store, profileId)) {
const cooldownUntil = resolveProfileUnusableUntil(store.usageStats?.[profileId] ?? {}) ?? now;
inCooldown.push({
profileId,
cooldownUntil
});
} else available.push(profileId);
const cooldownSorted = inCooldown.toSorted((a, b) => a.cooldownUntil - b.cooldownUntil).map((entry) => entry.profileId);
const ordered = [...available, ...cooldownSorted];
if (preferredProfile && ordered.includes(preferredProfile)) return [preferredProfile, ...ordered.filter((e) => e !== preferredProfile)];
return ordered;
}
const sorted = orderProfilesByMode(deduped, store);
if (preferredProfile && sorted.includes(preferredProfile)) return [preferredProfile, ...sorted.filter((e) => e !== preferredProfile)];
return sorted;
}
function resolveAuthOrder(order, provider) {
return findNormalizedProviderValue(order, provider);
}
function isNativeCredentialProviderCompatibleWithAuthProvider(params) {
if (!params.credential) return false;
return resolveProviderIdForAuth(params.credential.provider, { config: params.cfg }) === params.providerAuthKey;
}
function mergeAliasOrderWithNativeProfiles(params) {
const nativeIds = new Set(params.nativeProfiles);
return dedupeProfileIds(params.aliasOrder.some((profileId) => nativeIds.has(profileId)) ? [...params.aliasOrder, ...params.nativeProfiles] : [...params.nativeProfiles, ...params.aliasOrder]);
}
function orderProfilesByMode(order, store) {
const now = Date.now();
const available = [];
const inCooldown = [];
for (const profileId of order) if (isProfileInCooldown(store, profileId)) inCooldown.push(profileId);
else available.push(profileId);
const sorted = available.map((profileId) => {
const type = store.profiles[profileId]?.type;
return {
profileId,
typeScore: type === "oauth" ? 0 : type === "token" ? 1 : type === "api_key" ? 2 : 3,
lastUsed: store.usageStats?.[profileId]?.lastUsed ?? 0
};
}).toSorted((a, b) => {
if (a.typeScore !== b.typeScore) return a.typeScore - b.typeScore;
return a.lastUsed - b.lastUsed;
}).map((entry) => entry.profileId);
const cooldownSorted = inCooldown.map((profileId) => ({
profileId,
cooldownUntil: resolveProfileUnusableUntil(store.usageStats?.[profileId] ?? {}) ?? now
})).toSorted((a, b) => a.cooldownUntil - b.cooldownUntil).map((entry) => entry.profileId);
return [...sorted, ...cooldownSorted];
}
//#endregion
export { resolveAuthProfileOrder as i, isStoredCredentialCompatibleWithAuthProvider as n, resolveAuthProfileEligibility as r, isConfiguredAwsSdkAuthProfileForProvider as t };