UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

268 lines (267 loc) 10.7 kB
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 };