UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

163 lines (162 loc) 6.13 kB
import { i as normalizeProviderId } from "./provider-id-Dq06Bcx6.js"; import { y as resolveSessionAgentIds } from "./agent-scope-MrLta7Pq.js"; import { u as normalizeAgentId } from "./session-key-B_NoIfpX.js"; import { t as listAgentEntries } from "./agent-scope-config-CgCYpZfK.js"; //#region src/agents/model-runtime-policy.ts /** * Model runtime policy resolution. * * Agent execution uses this to choose a model/provider-specific runtime policy * from agent entries, model catalog config, provider config, or QA overrides. */ function hasRuntimePolicy(value) { return Boolean(value?.id?.trim()); } function resolveProviderConfig(config, provider) { if (!config?.models?.providers || !provider?.trim()) return; const providers = config.models.providers; const direct = providers[provider]; if (direct) return direct; const normalizedProvider = normalizeProviderId(provider); for (const [candidateProvider, providerConfig] of Object.entries(providers)) if (normalizeProviderId(candidateProvider) === normalizedProvider) return providerConfig; } function normalizeModelIdForProvider(provider, modelId) { const trimmed = modelId?.trim(); if (!trimmed) return; const slash = trimmed.indexOf("/"); if (slash <= 0) return trimmed; const modelProvider = normalizeProviderId(trimmed.slice(0, slash)); const expectedProvider = normalizeProviderId(provider ?? ""); if (expectedProvider && modelProvider !== expectedProvider) return; return trimmed.slice(slash + 1).trim() || void 0; } function parseProviderModelKey(key) { const slash = key.indexOf("/"); if (slash <= 0) return; const provider = normalizeProviderId(key.slice(0, slash)); const modelId = key.slice(slash + 1).trim(); return provider && modelId ? { provider, modelId } : void 0; } function providerMatchesCaller(provider, callerProvider) { return !callerProvider || provider === callerProvider; } function resolvePolicyMatch(matches, callerProvider) { const [first] = matches; if (!first) return {}; if (!callerProvider && matches.some((match) => match.provider !== first.provider)) return { ambiguous: true }; return { policy: first.policy, source: "model", matchedProvider: first.provider || callerProvider }; } function modelEntryMatches(params) { return modelEntryMatchKind(params) === "exact"; } function modelEntryMatchKind(params) { const entryId = params.entry.id.trim(); if (entryId === params.modelId) return "exact"; const parsed = parseProviderModelKey(entryId); if (!parsed) return "none"; const callerProvider = normalizeProviderId(params.provider ?? ""); if (!providerMatchesCaller(parsed.provider, callerProvider)) return "none"; if (parsed.modelId === params.modelId) return "exact"; if (parsed.modelId === "*") return "provider-wildcard"; return "none"; } function modelKeyMatchKind(params) { return modelEntryMatchKind({ entry: { id: params.key }, provider: params.provider, modelId: params.modelId }); } function modelKeyIsProviderWildcard(params) { const parsed = parseProviderModelKey(params.key); if (!parsed) return false; const callerProvider = normalizeProviderId(params.provider ?? ""); return parsed.modelId === "*" && providerMatchesCaller(parsed.provider, callerProvider); } function resolveAgentModelEntryRuntimePolicy(params) { const modelId = normalizeModelIdForProvider(params.provider, params.modelId); if (!params.config || !modelId && params.matchKind !== "provider-wildcard") return {}; const { sessionAgentId } = resolveSessionAgentIds({ config: params.config, agentId: params.agentId, sessionKey: params.sessionKey }); const modelMaps = [listAgentEntries(params.config).find((entry) => normalizeAgentId(entry.id) === sessionAgentId)?.models, params.config.agents?.defaults?.models]; const callerProvider = normalizeProviderId(params.provider ?? ""); for (const models of modelMaps) { const scopeMatches = []; for (const [key, entry] of Object.entries(models ?? {})) { const matches = modelId ? modelKeyMatchKind({ key, provider: params.provider, modelId }) === params.matchKind : modelKeyIsProviderWildcard({ key, provider: params.provider }); const policy = entry?.agentRuntime; if (!matches || !policy || !hasRuntimePolicy(policy)) continue; scopeMatches.push({ provider: parseProviderModelKey(key)?.provider ?? "", policy }); } const resolved = resolvePolicyMatch(scopeMatches, callerProvider); if (resolved.policy || resolved.ambiguous) return resolved; } return {}; } function resolveModelConfig(params) { const modelId = normalizeModelIdForProvider(params.provider, params.modelId); if (!modelId || !Array.isArray(params.providerConfig?.models)) return; return params.providerConfig.models.find((entry) => modelEntryMatches({ entry, provider: params.provider, modelId })); } /** Resolves the effective runtime policy for an agent/model/provider selection. */ function resolveModelRuntimePolicy(params) { if (process.env.OPENCLAW_BUILD_PRIVATE_QA === "1") { const forcedRuntime = process.env.OPENCLAW_QA_FORCE_RUNTIME?.trim().toLowerCase(); if (forcedRuntime === "openclaw" || forcedRuntime === "codex") return { policy: { id: forcedRuntime }, source: "model" }; } const agentModelPolicy = resolveAgentModelEntryRuntimePolicy({ ...params, matchKind: "exact" }); if (agentModelPolicy.ambiguous) return {}; if (agentModelPolicy.policy) return agentModelPolicy; const providerConfig = resolveProviderConfig(params.config, params.provider); const modelConfig = resolveModelConfig({ providerConfig, provider: params.provider, modelId: params.modelId }); if (hasRuntimePolicy(modelConfig?.agentRuntime)) return { policy: modelConfig?.agentRuntime, source: "model" }; const agentWildcardModelPolicy = resolveAgentModelEntryRuntimePolicy({ ...params, matchKind: "provider-wildcard" }); if (agentWildcardModelPolicy.policy) return agentWildcardModelPolicy; if (hasRuntimePolicy(providerConfig?.agentRuntime)) return { policy: providerConfig?.agentRuntime, source: "provider" }; return {}; } //#endregion export { resolveModelRuntimePolicy as t };