openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
268 lines (267 loc) • 10.7 kB
JavaScript
import { g as resolveConfiguredModelRef } from "./model-selection-shared-BlLyx1r2.js";
import { n as DEFAULT_MODEL, r as DEFAULT_PROVIDER } from "./defaults-CdX9UGcX.js";
import { a as resolveAgentModelPrimaryValue, i as resolveAgentModelFallbackValues, o as resolveAgentModelTimeoutMsValue } from "./model-input-BuGMCNOz.js";
import { T as overlayRuntimeExternalOAuthProfiles } from "./persisted-B_qhhBlh.js";
import { n as evaluateStoredCredentialEligibility } from "./credential-state-N1MIGw99.js";
import { s as resolveExternalCliAuthProfiles } from "./external-auth-D5zyqyNH.js";
import { a as ensureAuthProfileStoreWithoutExternalProfiles, r as ensureAuthProfileStore } from "./store-F1B2duCT.js";
import { t as hasAnyAuthProfileStoreSource } from "./source-check-BuLDxD9s.js";
import { n as listProfilesForProvider } from "./profile-list-DyfWX-d2.js";
import { a as resolveAuthProfileOrder } from "./order-CC2RBzI5.js";
import { t as resolveEnvApiKey } from "./model-auth-env-Dq9W4xg9.js";
import { n as externalCliDiscoveryForProviderAuth } from "./external-cli-discovery-CbeZXk1q.js";
import { b as resolveProviderEntryApiKeyProfileReference } from "./model-auth-provider-config-C_kr_q2g.js";
import "./auth-profiles-BdUEhE7u.js";
import { a as hasRuntimeAvailableProviderAuth } from "./model-auth-provider-Dd_3dXeY.js";
import "./model-auth-C48_DZ-I.js";
import "./model-selection-di2kjKCB.js";
//#region src/agents/tools/model-config.helpers.ts
/**
* Tool model config and auth helpers.
*
* Model-backed tools use this module to choose provider/model refs and check
* whether candidate providers have usable auth before exposing defaults.
*/
const OPENAI_PROVIDER_ID = "openai";
const CODEX_MEDIA_PROVIDER_ID = "codex";
const OPENAI_RESPONSES_MODEL_API = "openai-responses";
/** Returns whether a tool model config contains a primary or fallback model ref. */
function hasToolModelConfig(model) {
return Boolean(model?.primary?.trim() || (model?.fallbacks ?? []).some((entry) => entry.trim().length > 0));
}
/** Resolves the configured default model ref, falling back to OpenClaw defaults. */
function resolveDefaultModelRef(cfg) {
if (cfg) {
const resolved = resolveConfiguredModelRef({
cfg,
defaultProvider: DEFAULT_PROVIDER,
defaultModel: DEFAULT_MODEL
});
return {
provider: resolved.provider,
model: resolved.model
};
}
return {
provider: DEFAULT_PROVIDER,
model: DEFAULT_MODEL
};
}
/** Returns whether a provider has env, profile, or external CLI auth available. */
function hasAuthForProvider(params) {
if (!params.runtimeLookup && resolveEnvApiKey(params.provider, void 0, {
config: params.cfg,
workspaceDir: params.workspaceDir
})?.apiKey) return true;
return hasAuthProfileForProvider({
provider: params.provider,
agentDir: params.agentDir,
authStore: params.authStore,
includeExternalCli: true
});
}
/** Returns whether an auth profile exists for a provider, optionally filtered by type. */
function hasAuthProfileForProvider(params) {
let store = params.authStore;
if (!store) {
const agentDir = params.agentDir?.trim();
if (!agentDir) return false;
if (!hasAnyAuthProfileStoreSource(agentDir)) return false;
store = params.includeExternalCli ? ensureAuthProfileStore(agentDir, { externalCli: externalCliDiscoveryForProviderAuth({ provider: params.provider }) }) : ensureAuthProfileStoreWithoutExternalProfiles(agentDir, { allowKeychainPrompt: false });
}
const profileIds = listProfilesForProvider(store, params.provider);
if (!params.type) return profileIds.length > 0;
return profileIds.some((profileId) => store.profiles[profileId]?.type === params.type);
}
/** Returns whether a provider can be used by a model-backed tool. */
function hasProviderAuthForTool(params) {
if (hasRuntimeAvailableProviderAuth({
provider: params.provider,
cfg: params.cfg,
workspaceDir: params.workspaceDir,
allowPluginSyntheticAuth: false,
runtimeLookup: params.runtimeLookup,
store: loadAuthStoreForProvider({
provider: params.provider,
cfg: params.cfg,
agentDir: params.agentDir,
authStore: params.authStore
})
})) return true;
return hasAuthForProvider({
provider: params.provider,
cfg: params.cfg,
workspaceDir: params.workspaceDir,
agentDir: params.agentDir,
authStore: params.authStore,
runtimeLookup: params.runtimeLookup
});
}
function formatProviderModelRef(provider, model) {
return `${provider}/${model}`;
}
function loadAuthStoreForProvider(params) {
if (params.authStore) return params.authStore;
const agentDir = params.agentDir?.trim();
if (!agentDir) return;
return params.includeExternalCli ? ensureAuthProfileStore(agentDir, { externalCli: externalCliDiscoveryForProviderAuth({
provider: params.provider,
cfg: params.cfg
}) }) : ensureAuthProfileStoreWithoutExternalProfiles(agentDir, { allowKeychainPrompt: false });
}
function overlayExternalCliAuthStoreForProvider(params) {
const profiles = resolveExternalCliAuthProfiles(params.authStore, {
allowKeychainPrompt: false,
providerIds: [params.provider]
});
if (profiles.length === 0) return params.authStore;
return overlayRuntimeExternalOAuthProfiles(params.authStore, profiles);
}
function hasAuthProfileTypeInStore(params) {
const types = Array.isArray(params.type) ? params.type : [params.type];
return resolveAuthProfileOrder({
cfg: params.cfg,
store: params.store,
provider: params.provider
}).some((profileId) => types.includes(params.store.profiles[profileId]?.type));
}
function hasAuthProfileTypeForProvider(params) {
const store = loadAuthStoreForProvider(params);
if (store && hasAuthProfileTypeInStore({
...params,
store
})) return true;
if (params.includeExternalCli && params.authStore) {
const externalStore = overlayExternalCliAuthStoreForProvider({
provider: params.provider,
authStore: params.authStore
});
return hasAuthProfileTypeInStore({
...params,
store: externalStore
});
}
return false;
}
/** Returns whether a provider has direct API-key-capable auth for model-backed tools. */
function hasDirectProviderApiKeyAuthForTool(params) {
const providerEntryProfileAuth = resolveDirectProviderEntryAuthFromProfileReference(params);
if (providerEntryProfileAuth !== void 0) return providerEntryProfileAuth;
if (hasRuntimeAvailableProviderAuth({
provider: params.provider,
cfg: params.cfg,
workspaceDir: params.workspaceDir,
modelApi: params.modelApi,
allowPluginSyntheticAuth: false,
store: loadAuthStoreForProvider({
provider: params.provider,
cfg: params.cfg,
agentDir: params.agentDir,
authStore: params.authStore
})
})) return true;
return hasAuthProfileTypeForProvider({
provider: params.provider,
cfg: params.cfg,
agentDir: params.agentDir,
authStore: params.authStore,
type: "api_key"
});
}
if (process.env.VITEST || false) globalThis[Symbol.for("openclaw.modelConfigHelpersTestApi")] = { hasDirectProviderApiKeyAuthForTool };
function hasCanonicalOpenAiCodexAuthSignal(params) {
return hasAuthProfileTypeForProvider({
provider: OPENAI_PROVIDER_ID,
cfg: params.cfg,
agentDir: params.agentDir,
authStore: params.authStore,
includeExternalCli: true,
type: ["oauth", "token"]
});
}
function resolveDirectProviderEntryAuthFromProfileReference(params) {
const resolveFromStore = (store) => {
const reference = resolveProviderEntryApiKeyProfileReference({
cfg: params.cfg,
provider: params.provider,
store
});
if (reference.kind === "profile") return reference.credential.type === "api_key" && evaluateStoredCredentialEligibility({ credential: reference.credential }).eligible;
if (reference.kind === "profile-incompatible") return false;
};
const store = loadAuthStoreForProvider({
provider: params.provider,
cfg: params.cfg,
agentDir: params.agentDir,
authStore: params.authStore,
includeExternalCli: true
});
const storeResult = store ? resolveFromStore(store) : void 0;
if (storeResult !== void 0) return storeResult;
if (params.authStore) return resolveFromStore(overlayExternalCliAuthStoreForProvider({
provider: params.provider,
authStore: params.authStore
}));
}
/** Resolves the implicit OpenAI image slot without letting OAuth-only auth pick direct OpenAI. */
function resolveOpenAiImageMediaCandidate(params) {
const openAiModel = params.openAiModel.trim();
if (!openAiModel) return { kind: "drop" };
if (hasDirectProviderApiKeyAuthForTool({
provider: OPENAI_PROVIDER_ID,
cfg: params.cfg,
workspaceDir: params.workspaceDir,
agentDir: params.agentDir,
authStore: params.authStore,
modelApi: OPENAI_RESPONSES_MODEL_API
})) return {
kind: "keep",
ref: formatProviderModelRef(OPENAI_PROVIDER_ID, openAiModel)
};
if (!hasCanonicalOpenAiCodexAuthSignal(params)) return { kind: "drop" };
const codexModel = params.resolveCodexMediaRoute?.()?.model.trim();
if (codexModel) return {
kind: "substitute",
provider: CODEX_MEDIA_PROVIDER_ID,
ref: formatProviderModelRef(CODEX_MEDIA_PROVIDER_ID, codexModel)
};
return { kind: "drop" };
}
/** Normalizes agent tool model config into a compact runtime shape. */
function coerceToolModelConfig(model) {
const primary = resolveAgentModelPrimaryValue(model);
const fallbacks = resolveAgentModelFallbackValues(model);
const timeoutMs = resolveAgentModelTimeoutMsValue(model);
return {
...primary?.trim() ? { primary: primary.trim() } : {},
...fallbacks.length > 0 ? { fallbacks } : {},
...timeoutMs !== void 0 ? { timeoutMs } : {}
};
}
/** Builds a tool model config from configured auth-aware candidate model refs. */
function buildToolModelConfigFromCandidates(params) {
if (hasToolModelConfig(params.explicit)) return params.explicit;
const deduped = [];
for (const candidate of params.candidates) {
const trimmed = candidate?.trim();
if (!trimmed || !trimmed.includes("/")) continue;
const provider = trimmed.slice(0, trimmed.indexOf("/")).trim();
const providerConfigured = params.isProviderConfigured?.(provider) ?? hasProviderAuthForTool({
provider,
cfg: params.cfg,
workspaceDir: params.workspaceDir,
agentDir: params.agentDir,
authStore: params.authStore
});
if (!provider || !providerConfigured) continue;
if (!deduped.includes(trimmed)) deduped.push(trimmed);
}
if (deduped.length === 0) return null;
return {
primary: deduped[0],
...deduped.length > 1 ? { fallbacks: deduped.slice(1) } : {},
...params.explicit.timeoutMs !== void 0 ? { timeoutMs: params.explicit.timeoutMs } : {}
};
}
//#endregion
export { hasProviderAuthForTool as a, resolveOpenAiImageMediaCandidate as c, hasAuthProfileForProvider as i, coerceToolModelConfig as n, hasToolModelConfig as o, hasAuthForProvider as r, resolveDefaultModelRef as s, buildToolModelConfigFromCandidates as t };