openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
468 lines (467 loc) • 17.8 kB
JavaScript
import { h as normalizeUniqueStringEntries } from "./string-normalization-DsCfAx8q.js";
import { n as getRuntimeConfig } from "./io.runtime-B9iJRs3w.js";
import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js";
import { l as normalizePluginsConfig } from "./config-state-BkU1frVq.js";
import { i as passesManifestOwnerBasePolicy, n as isActivatedManifestOwner } from "./manifest-owner-policy-D98oU3cV.js";
import { c as normalizeProviderId } from "./model-ref-shared-Dz7QU0Lx.js";
import { c as loadManifestMetadataSnapshot } from "./manifest-contract-eligibility-BbV7X6pV.js";
import { a as resolveProviderAuthEnvVarCandidates } from "./provider-env-vars-B8XgJCSL.js";
import "./config-Cs0XXL3x.js";
import { i as trackAsyncWork } from "./async-work-scope-CMQS2uTf.js";
import { n as resolveApiKeyForProfile } from "./oauth-BNreHOU-.js";
import { n as normalizeSecretInput } from "./normalize-secret-input-Df_qhWv_.js";
import { a as ensureAuthProfileStoreWithoutExternalProfiles, r as ensureAuthProfileStore } from "./store-F1B2duCT.js";
import { t as hasAnyAuthProfileStoreSource } from "./source-check-BuLDxD9s.js";
import { t as dedupeProfileIds } from "./profile-list-DyfWX-d2.js";
import { a as resolveAuthProfileOrder } from "./order-CC2RBzI5.js";
import { c as isNonSecretApiKeyMarker } from "./model-auth-markers-jBKQn38x.js";
import { a as isOAuthOnlyUsageProvider, i as ignoredErrors, o as providerUsageLabel, s as raceUsageTimeout } from "./provider-usage.shared-BKgwfwAS.js";
import { M as resolveProviderUsageAuthWithPlugin, N as resolveProviderUsageSnapshotWithPlugin, l as listProviderUsagePluginDescriptors } from "./provider-runtime-BRJDPNgk.js";
import { t as resolveEnvApiKey } from "./model-auth-env-Dq9W4xg9.js";
import { S as resolveUsableCustomProviderApiKey } from "./model-auth-provider-config-C_kr_q2g.js";
import "./auth-profiles-BdUEhE7u.js";
import "./model-auth-C48_DZ-I.js";
import "./model-selection-di2kjKCB.js";
import { i as resolveProxyFetchFromEnv } from "./proxy-fetch-BdRrrR-3.js";
import { t as resolveFetch } from "./fetch-Dg9e8ALx.js";
//#region src/infra/provider-usage.auth.ts
function resolveUsageAuthStore(state) {
state.store ??= state.getStore?.() ?? ensureAuthProfileStore(state.agentDir, { allowKeychainPrompt: false });
return state.store;
}
function resolveProviderApiKeyFromConfig(params) {
const envDirect = params.envDirect?.map(normalizeSecretInput).find(Boolean);
if (envDirect) return envDirect;
for (const providerId of params.providerIds) {
const envKey = resolveEnvApiKey(providerId, params.state.env)?.apiKey;
if (envKey) return envKey;
const key = resolveUsableCustomProviderApiKey({
cfg: params.state.cfg,
provider: providerId,
env: params.state.env
})?.apiKey;
if (key) return key;
}
}
function hasProviderAuthEnvCredentialSource(params) {
const candidates = resolveProviderAuthEnvVarCandidates({
config: params.state.cfg,
env: {
...process.env.VITEST ? process.env : {},
...params.state.env
}
});
for (const providerId of normalizeProviderIds(params.providerIds)) {
const envVars = Object.hasOwn(candidates, providerId) ? candidates[providerId] : void 0;
if (!envVars) continue;
if (envVars.some((envVar) => Boolean(normalizeSecretInput(params.state.env[envVar])))) return true;
}
return false;
}
function hasProviderUsageAuthEnvCredentialSource(params) {
const providerIds = new Set(normalizeProviderIds(params.providerIds));
try {
return loadManifestMetadataSnapshot({
config: params.state.cfg,
env: params.state.env
}).plugins.some((plugin) => {
if (!isUsageProviderManifestEligible({
plugin,
state: params.state
})) return false;
return Object.entries(plugin.providerUsageAuthEnvVars ?? {}).some(([providerId, envVars]) => providerIds.has(normalizeProviderId(providerId)) && envVars.some((envVar) => Boolean(normalizeSecretInput(params.state.env[envVar]))));
});
} catch {
return false;
}
}
function resolveProviderApiKeyFromConfigAndStore(params) {
return resolveProviderApiKeyCandidatesFromConfigAndStoreSync(params)[0];
}
function resolveProviderApiKeyCandidatesFromConfigAndStoreSync(params) {
const candidates = [];
const configKey = resolveProviderApiKeyFromConfig(params);
if (configKey) candidates.push(configKey);
if (!params.state.allowAuthProfileStore) return candidates;
const normalizedProviderIds = new Set(normalizeUniqueStringEntries(params.providerIds.map((providerId) => normalizeProviderId(providerId))));
const store = resolveUsageAuthStore(params.state);
const credentials = [...normalizedProviderIds].flatMap((provider) => resolveAuthProfileOrder({
cfg: params.state.cfg,
store,
provider
})).map((id) => store.profiles[id]).filter((profile) => profile?.type === "api_key" || profile?.type === "token");
for (const credential of credentials) {
const value = normalizeSecretInput(credential.type === "api_key" ? credential.key : credential.token);
if (value && !isNonSecretApiKeyMarker(value)) candidates.push(value);
}
return normalizeUniqueStringEntries(candidates);
}
async function resolveProviderApiKeyCandidatesFromConfigAndStore(params) {
const candidates = [];
const configKey = resolveProviderApiKeyFromConfig(params);
if (configKey) candidates.push(configKey);
if (!params.state.allowAuthProfileStore) return candidates;
const store = resolveUsageAuthStore(params.state);
const profileIds = dedupeProfileIds(normalizeProviderIds(params.providerIds).flatMap((provider) => resolveAuthProfileOrder({
cfg: params.state.cfg,
store,
provider
})));
for (const profileId of profileIds) {
const credential = store.profiles[profileId];
if (!credential || credential.type !== "api_key" && credential.type !== "token") continue;
let resolved;
try {
resolved = await resolveApiKeyForProfile({
cfg: params.state.cfg,
store,
profileId,
agentDir: params.state.agentDir
});
} catch {
continue;
}
const value = normalizeSecretInput(resolved?.apiKey);
if (value && !isNonSecretApiKeyMarker(value)) candidates.push(value);
}
return normalizeUniqueStringEntries(candidates);
}
function normalizeProviderIds(providerIds) {
return [...new Set([...providerIds].map((providerId) => providerId ? normalizeProviderId(providerId) : void 0).filter((providerId) => Boolean(providerId)))];
}
function isUsageProviderManifestEligible(params) {
const normalizedConfig = normalizePluginsConfig(params.state.cfg.plugins);
if (!passesManifestOwnerBasePolicy({
plugin: params.plugin,
normalizedConfig
})) return false;
if (params.plugin.origin !== "workspace") return true;
return isActivatedManifestOwner({
plugin: params.plugin,
normalizedConfig,
rootConfig: params.state.cfg
});
}
function resolveUsageCredentialProviderIds(params) {
const providerIds = new Set(normalizeProviderIds([params.provider]));
const providerIdSet = new Set(providerIds);
try {
const snapshot = loadManifestMetadataSnapshot({
config: params.state.cfg,
env: params.state.env
});
for (const plugin of snapshot.plugins) {
const pluginProviderIds = normalizeProviderIds(plugin.providers);
if (!pluginProviderIds.some((providerId) => providerIdSet.has(providerId))) continue;
if (!isUsageProviderManifestEligible({
plugin,
state: params.state
})) continue;
for (const providerId of pluginProviderIds) providerIds.add(providerId);
}
} catch {}
return [...providerIds];
}
async function resolveOAuthToken(params) {
if (!params.state.allowAuthProfileStore) return null;
const store = resolveUsageAuthStore(params.state);
const order = resolveAuthProfileOrder({
cfg: params.state.cfg,
store,
provider: params.provider
});
const deduped = dedupeProfileIds(order);
const excludedProfileIds = new Set(params.excludeProfileIds ?? []);
for (const profileId of deduped) {
if (excludedProfileIds.has(profileId)) continue;
const cred = store.profiles[profileId];
if (!cred || cred.type !== "oauth" && cred.type !== "token") continue;
try {
const resolved = await resolveApiKeyForProfile({
cfg: params.state.cfg,
store,
profileId,
agentDir: params.state.agentDir
});
if (!resolved) continue;
return {
provider: params.provider,
token: resolved.apiKey,
accountId: cred.type === "oauth" && "accountId" in cred ? cred.accountId : void 0,
...cred.type === "oauth" && cred.subscriptionType ? { subscriptionType: cred.subscriptionType } : {},
...cred.type === "oauth" && cred.rateLimitTier ? { rateLimitTier: cred.rateLimitTier } : {},
...cred.email ? { email: cred.email } : {}
};
} catch {}
}
return null;
}
async function resolveProviderUsageAuthViaPlugin(params) {
const resolved = await resolveProviderUsageAuthWithPlugin({
provider: params.provider,
config: params.state.cfg,
env: params.state.env,
context: {
config: params.state.cfg,
agentDir: params.state.agentDir,
env: params.state.env,
provider: params.provider,
resolveApiKeyFromConfigAndStore: (options) => resolveProviderApiKeyFromConfigAndStore({
state: params.state,
providerIds: options?.providerIds ?? [params.provider],
envDirect: options?.envDirect
}),
resolveApiKeyCandidatesFromConfigAndStore: (options) => resolveProviderApiKeyCandidatesFromConfigAndStore({
state: params.state,
providerIds: options?.providerIds ?? [params.provider],
envDirect: options?.envDirect
}),
resolveOAuthToken: async (options) => {
const auth = await resolveOAuthToken({
state: params.state,
provider: options?.provider ?? params.provider,
excludeProfileIds: options?.excludeProfileIds
});
return auth ? {
token: auth.token,
...auth.accountId ? { accountId: auth.accountId } : {},
...auth.subscriptionType ? { subscriptionType: auth.subscriptionType } : {},
...auth.rateLimitTier ? { rateLimitTier: auth.rateLimitTier } : {},
...auth.email ? { email: auth.email } : {}
} : null;
}
}
});
if (!resolved) return {
handled: false,
auth: null
};
if ("handled" in resolved) return {
handled: true,
auth: null
};
return {
handled: true,
auth: {
provider: params.provider,
token: resolved.token,
...resolved.accountId ? { accountId: resolved.accountId } : {},
...resolved.subscriptionType ? { subscriptionType: resolved.subscriptionType } : {},
...resolved.rateLimitTier ? { rateLimitTier: resolved.rateLimitTier } : {},
...resolved.email ? { email: resolved.email } : {}
}
};
}
async function resolveProviderUsageAuthFallback(params) {
const oauthToken = await resolveOAuthToken({
state: params.state,
provider: params.provider
});
if (oauthToken) return oauthToken;
if (isOAuthOnlyUsageProvider(params.provider)) return null;
const apiKey = resolveProviderApiKeyFromConfigAndStore({
state: params.state,
providerIds: [params.provider]
});
if (apiKey) return {
provider: params.provider,
token: apiKey
};
return null;
}
function hasAuthProfileCredentialSource(params) {
const store = params.state.store ??= params.state.getStore?.() ?? ensureAuthProfileStoreWithoutExternalProfiles(params.state.agentDir, { allowKeychainPrompt: false });
for (const provider of params.providerIds) {
const order = resolveAuthProfileOrder({
cfg: params.state.cfg,
store,
provider
});
if (dedupeProfileIds(order).some((profileId) => {
const cred = store.profiles[profileId];
return cred?.type === "oauth" || cred?.type === "token" || cred?.type === "api_key";
})) return true;
}
return false;
}
async function resolveProviderAuths(params) {
if (params.auth) return params.auth;
const stateBase = {
cfg: params.config ?? getRuntimeConfig(),
env: params.env ?? process.env,
agentDir: params.agentDir
};
const authProfileSourceState = {
...stateBase,
allowAuthProfileStore: true,
getStore: params.getStore,
store: params.store
};
const hasAuthProfileStoreSource = params.store !== void 0 || params.getStore !== void 0 || hasAnyAuthProfileStoreSource(params.agentDir);
const auths = [];
for (const provider of params.providers) try {
const directCredentialState = {
...stateBase,
allowAuthProfileStore: false
};
const credentialProviderIds = resolveUsageCredentialProviderIds({
state: directCredentialState,
provider
});
const hasDirectCredentialSource = Boolean(resolveProviderApiKeyFromConfig({
state: directCredentialState,
providerIds: credentialProviderIds
})) || hasProviderAuthEnvCredentialSource({
state: directCredentialState,
providerIds: credentialProviderIds
}) || hasProviderUsageAuthEnvCredentialSource({
state: directCredentialState,
providerIds: credentialProviderIds
});
const allowAuthProfileStore = hasDirectCredentialSource || hasAuthProfileStoreSource && hasAuthProfileCredentialSource({
state: authProfileSourceState,
providerIds: credentialProviderIds
});
const state = {
...authProfileSourceState,
allowAuthProfileStore
};
if (hasDirectCredentialSource || allowAuthProfileStore) {
const pluginAuth = await resolveProviderUsageAuthViaPlugin({
state,
provider
});
if (pluginAuth.auth) {
auths.push(pluginAuth.auth);
continue;
}
if (pluginAuth.handled) continue;
}
const fallbackAuth = await resolveProviderUsageAuthFallback({
state,
provider
});
if (fallbackAuth) auths.push(fallbackAuth);
} catch (error) {
if (!params.onError) throw error;
params.onError(provider, error);
}
return auths;
}
//#endregion
//#region src/infra/provider-usage.load.ts
async function fetchProviderUsageSnapshotFallback(params) {
params.timeoutMs;
params.fetchFn;
return {
provider: params.auth.provider,
displayName: providerUsageLabel(params.auth.provider) ?? params.auth.provider,
windows: [],
error: "Unsupported provider"
};
}
async function fetchProviderUsageSnapshot(params) {
const pluginSnapshot = await resolveProviderUsageSnapshotWithPlugin({
provider: params.auth.hookProvider ?? params.auth.provider,
config: params.config,
workspaceDir: params.workspaceDir,
env: params.env,
context: {
config: params.config,
agentDir: params.agentDir,
workspaceDir: params.workspaceDir,
env: params.env,
provider: params.auth.provider,
token: params.auth.token,
accountId: params.auth.accountId,
authProfileId: params.auth.authProfileId,
subscriptionType: params.auth.subscriptionType,
rateLimitTier: params.auth.rateLimitTier,
email: params.auth.email,
timeoutMs: params.timeoutMs,
fetchFn: params.fetchFn
}
});
if (pluginSnapshot) return pluginSnapshot;
return await fetchProviderUsageSnapshotFallback({
auth: params.auth,
timeoutMs: params.timeoutMs,
fetchFn: params.fetchFn
});
}
/** Loads usage snapshots from configured provider auth and plugin-backed usage hooks. */
async function loadProviderUsageSummary(opts = {}) {
const now = opts.now ?? Date.now();
const timeoutMs = opts.timeoutMs ?? 5e3;
const config = opts.config ?? getRuntimeConfig();
const env = opts.env ?? process.env;
const fetchFn = opts.fetch ? resolveFetch(opts.fetch) : resolveProxyFetchFromEnv(env) ?? resolveFetch();
if (!fetchFn) throw new Error("fetch is not available");
const descriptors = opts.providers ? opts.providers.map((provider) => ({
provider,
displayName: providerUsageLabel(provider) ?? provider
})) : opts.auth ? opts.auth.map((auth) => ({
provider: auth.provider,
displayName: providerUsageLabel(auth.provider) ?? auth.provider
})) : listProviderUsagePluginDescriptors({
config,
workspaceDir: opts.workspaceDir,
env
});
const displayNames = new Map(descriptors.map((descriptor) => [descriptor.provider, descriptor.displayName]));
const providerOrder = new Map(descriptors.map(({ provider }, index) => [provider, index]));
const failureSnapshot = (provider, error) => ({
provider,
displayName: displayNames.get(provider) ?? providerUsageLabel(provider) ?? provider,
windows: [],
error
});
let authStore = opts.authStore;
const getAuthStore = () => authStore ??= ensureAuthProfileStore(opts.agentDir, { allowKeychainPrompt: false });
const tasks = descriptors.map(({ provider }) => {
return raceUsageTimeout(trackAsyncWork(async () => {
let authError;
const auth = opts.auth?.find((candidate) => candidate.provider === provider) ?? (await resolveProviderAuths({
providers: [provider],
agentDir: opts.agentDir,
config,
env,
getStore: getAuthStore,
store: opts.authStore,
onError: (_provider, error) => {
authError = error;
}
}))[0];
if (authError) {
const message = formatErrorMessage(authError);
return failureSnapshot(provider, message.trim() || "Auth failed");
}
if (!auth) return;
return await fetchProviderUsageSnapshot({
auth,
config,
env,
agentDir: opts.agentDir,
workspaceDir: opts.workspaceDir,
timeoutMs,
fetchFn
});
}), timeoutMs, failureSnapshot(provider, "Timeout")).catch((error) => {
const message = error instanceof Error ? error.message : String(error);
return failureSnapshot(provider, message.trim() || "Fetch failed");
});
});
return {
updatedAt: now,
providers: (await Promise.all(tasks)).filter((snapshot) => snapshot !== void 0).toSorted((left, right) => (providerOrder.get(left.provider) ?? Number.MAX_SAFE_INTEGER) - (providerOrder.get(right.provider) ?? Number.MAX_SAFE_INTEGER)).filter((entry) => {
if (entry.windows.length > 0) return true;
if (entry.billing && entry.billing.length > 0) return true;
if (entry.costHistory?.daily.length) return true;
if (entry.summary?.trim()) return true;
if (!entry.error) return true;
return !ignoredErrors.has(entry.error);
})
};
}
//#endregion
export { loadProviderUsageSummary as t };