UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

138 lines (137 loc) 7.84 kB
import { l as normalizeStringEntries } from "./string-normalization-WNUDCpXX.js"; import { r as resolveProviderRequestCapabilities } from "./provider-attribution-GEHCfopl.js"; //#region src/agents/openai-completions-compat.ts function isDefaultRouteProvider(provider, ...ids) { return provider !== void 0 && ids.includes(provider); } /** Resolves default request flags for an OpenAI-compatible completions endpoint. */ function resolveOpenAICompletionsCompatDefaults(input) { const { provider, endpointClass, knownProviderFamily, supportsNativeStreamingUsageCompat = false, supportsOpenAICompletionsStreamingUsageCompat = false, usesExplicitProxyLikeEndpoint = false } = input; const isDefaultRoute = endpointClass === "default"; const usesConfiguredNonOpenAIEndpoint = endpointClass !== "default" && endpointClass !== "openai-public"; const isMoonshotLike = knownProviderFamily === "moonshot" || knownProviderFamily === "modelstudio" || endpointClass === "moonshot-native" || endpointClass === "modelstudio-native"; const isModelStudioLike = knownProviderFamily === "modelstudio" || endpointClass === "modelstudio-native" || isDefaultRoute && isDefaultRouteProvider(provider, "dashscope", "modelstudio", "qwen"); const isZai = endpointClass === "zai-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "zai"); const isDeepSeek = endpointClass === "deepseek-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "deepseek"); const isTogether = knownProviderFamily === "together" || isDefaultRoute && isDefaultRouteProvider(input.provider, "together"); const isXiaomi = endpointClass === "xiaomi-native" || isDefaultRoute && isDefaultRouteProvider(input.provider, "xiaomi"); const isNonStandard = endpointClass === "cerebras-native" || endpointClass === "chutes-native" || endpointClass === "deepseek-native" || endpointClass === "mistral-public" || endpointClass === "opencode-native" || endpointClass === "xai-native" || isXiaomi || isZai || isDefaultRoute && isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai"); const isOpenRouterLike = input.provider === "openrouter" || endpointClass === "openrouter"; const isLocalEndpoint = endpointClass === "local"; const usesMaxTokens = endpointClass === "chutes-native" || endpointClass === "mistral-public" || knownProviderFamily === "mistral" || isTogether || isDefaultRoute && isDefaultRouteProvider(provider, "chutes"); return { supportsStore: !isNonStandard && knownProviderFamily !== "mistral" && !usesExplicitProxyLikeEndpoint, supportsDeveloperRole: !isNonStandard && !isMoonshotLike && !usesConfiguredNonOpenAIEndpoint, supportsReasoningEffort: !isZai && !isTogether && knownProviderFamily !== "mistral" && endpointClass !== "xai-native" && !usesExplicitProxyLikeEndpoint, supportsUsageInStreaming: supportsOpenAICompletionsStreamingUsageCompat || !isNonStandard && (isLocalEndpoint || !usesConfiguredNonOpenAIEndpoint || supportsNativeStreamingUsageCompat), maxTokensField: usesMaxTokens ? "max_tokens" : "max_completion_tokens", thinkingFormat: isDeepSeek || isXiaomi ? "deepseek" : isZai ? "zai" : isTogether ? "together" : isOpenRouterLike ? "openrouter" : "openai", visibleReasoningDetailTypes: isOpenRouterLike ? ["response.output_text", "response.text"] : [], supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint, requiresReasoningContentOnAssistantMessages: isDeepSeek || isXiaomi, requiresNonEmptyUserOrAssistantMessage: isModelStudioLike }; } function resolveOpenAICompletionsCompatDefaultsFromCapabilities(input) { return resolveOpenAICompletionsCompatDefaults(input); } /** Detects endpoint capabilities and defaults for an OpenAI-completions model. */ function detectOpenAICompletionsCompat(model) { const capabilities = resolveProviderRequestCapabilities({ provider: model.provider, api: "openai-completions", baseUrl: model.baseUrl, capability: "llm", transport: "stream", modelId: model.id, compat: model.compat && typeof model.compat === "object" ? model.compat : void 0 }); return { capabilities, defaults: resolveOpenAICompletionsCompatDefaultsFromCapabilities({ provider: model.provider, ...capabilities }) }; } //#endregion //#region src/plugins/provider-model-compat.ts function extractModelCompat(modelOrCompat) { if (!modelOrCompat || typeof modelOrCompat !== "object") return; if ("compat" in modelOrCompat) { const compat = modelOrCompat.compat; return compat && typeof compat === "object" ? compat : void 0; } return modelOrCompat; } /** @deprecated Provider-owned model compat helper; do not use from third-party plugins. */ function applyModelCompatPatch(model, patch) { const nextCompat = { ...model.compat, ...patch }; const currentCompat = model.compat; if (model.compat && Object.entries(patch).every(([key, value]) => currentCompat?.[key] === value)) return model; return { ...model, compat: nextCompat }; } function hasToolSchemaProfile(modelOrCompat, profile) { return extractModelCompat(modelOrCompat)?.toolSchemaProfile === profile; } function hasNativeWebSearchTool(modelOrCompat) { return extractModelCompat(modelOrCompat)?.nativeWebSearchTool === true; } function resolveToolCallArgumentsEncoding(modelOrCompat) { return extractModelCompat(modelOrCompat)?.toolCallArgumentsEncoding; } function resolveUnsupportedToolSchemaKeywords(modelOrCompat) { const keywords = extractModelCompat(modelOrCompat)?.unsupportedToolSchemaKeywords ?? []; return new Set(normalizeStringEntries(keywords.filter((keyword) => typeof keyword === "string"))); } function shouldOmitEmptyArrayItems(modelOrCompat) { return extractModelCompat(modelOrCompat)?.omitEmptyArrayItems === true; } function isOpenAiCompletionsModel(model) { return model.api === "openai-completions"; } function isAnthropicMessagesModel(model) { return model.api === "anthropic-messages"; } function normalizeAnthropicBaseUrl(baseUrl) { return baseUrl.replace(/\/v1\/?$/, ""); } function normalizeModelCompat(model) { const baseUrl = model.baseUrl ?? ""; if (isAnthropicMessagesModel(model) && baseUrl) { const normalized = normalizeAnthropicBaseUrl(baseUrl); if (normalized !== baseUrl) return { ...model, baseUrl: normalized }; } if (!isOpenAiCompletionsModel(model)) return model; const compat = model.compat ?? void 0; const detectedCompatDefaults = baseUrl ? detectOpenAICompletionsCompat(model).defaults : void 0; if (!Boolean(detectedCompatDefaults && (!detectedCompatDefaults.supportsDeveloperRole || !detectedCompatDefaults.supportsUsageInStreaming || !detectedCompatDefaults.supportsStrictMode))) return model; const forcedDeveloperRole = compat?.supportsDeveloperRole === true; const hasStreamingUsageOverride = compat?.supportsUsageInStreaming !== void 0; const targetStrictMode = compat?.supportsStrictMode ?? detectedCompatDefaults?.supportsStrictMode; if (compat?.supportsDeveloperRole !== void 0 && hasStreamingUsageOverride && compat?.supportsStrictMode !== void 0) return model; return { ...model, compat: compat ? { ...compat, supportsDeveloperRole: forcedDeveloperRole || false, ...hasStreamingUsageOverride ? {} : { supportsUsageInStreaming: detectedCompatDefaults?.supportsUsageInStreaming ?? false }, supportsStrictMode: targetStrictMode } : { supportsDeveloperRole: false, supportsUsageInStreaming: detectedCompatDefaults?.supportsUsageInStreaming ?? false, supportsStrictMode: detectedCompatDefaults?.supportsStrictMode ?? false } }; } //#endregion export { normalizeModelCompat as a, shouldOmitEmptyArrayItems as c, hasToolSchemaProfile as i, detectOpenAICompletionsCompat as l, extractModelCompat as n, resolveToolCallArgumentsEncoding as o, hasNativeWebSearchTool as r, resolveUnsupportedToolSchemaKeywords as s, applyModelCompatPatch as t };