UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

273 lines (272 loc) 11.4 kB
import { a as asOptionalRecord } from "./record-coerce-DItp3I4t.js"; import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js"; import { y as resolveDefaultAgentId } from "./agent-scope-config-DcbEhP0R.js"; import { o as resolveAgentEffectiveModelPrimary, w as setAgentEffectiveModelPrimary } from "./agent-scope-DbtJyKUL.js"; import "./string-coerce-runtime-GQa0ehRA.js"; import "./agent-runtime-B15RhSG0.js"; import { v as resolveMigrationConfigRuntime } from "./migration-q6QzXKht.js"; import { a as HERMES_REASON_DEFAULT_MODEL_CONFIGURED, g as readHermesModelDetails, h as hermesItemSkipped, i as HERMES_REASON_CONFIG_RUNTIME_UNAVAILABLE, m as hermesItemError, p as hermesItemConflict, t as HERMES_REASON_ALREADY_CONFIGURED } from "./items-BfpzP26U.js"; //#region extensions/migrate-hermes/model.ts const HERMES_PROVIDER_ALIASES = { alibaba: "qwen", "alibaba-cloud": "qwen", "alibaba-coding": "qwen", "alibaba-coding-plan": "qwen", alibaba_coding: "qwen", alibaba_coding_plan: "qwen", aliyun: "qwen", "azure-foundry": "microsoft-foundry", bedrock: "amazon-bedrock", claude: "anthropic", "claude-code": "anthropic", copilot: "github-copilot", gemini: "google", github: "github-copilot", "github-copilot": "github-copilot", "github-model": "github-copilot", "github-models": "github-copilot", glm: "zai", google: "google", "google-ai-studio": "google", "google-gemini": "google", grok: "xai", kilo: "kilocode", "kilo-code": "kilocode", "kilo-gateway": "kilocode", kimi: "kimi", "kimi-cn": "moonshot", "kimi-for-coding": "kimi", "kimi-coding": "kimi", "kimi-coding-cn": "moonshot", "moonshot-cn": "moonshot", moonshot: "moonshot", "minimax-global": "minimax-portal", "minimax-cn": "minimax", "minimax-oauth": "minimax-portal", "minimax-portal": "minimax-portal", minimax_oauth: "minimax-portal", "opencode-zen": "opencode", "openai-api": "openai", "openai-codex": "openai", dashscope: "qwen", qwen: "qwen", "qwen-cli": "qwen", "qwen-oauth": "qwen", "qwen-portal": "qwen", "x-ai": "xai", "x-ai-oauth": "xai", "x.ai": "xai", "xai-grok-oauth": "xai", "xai-oauth": "xai", "grok-oauth": "xai", "z-ai": "zai", "z.ai": "zai", zen: "opencode", zhipu: "zai", vertex: "google-vertex" }; const HERMES_CANONICAL_PROVIDER_IDS = /* @__PURE__ */ new Set([ "alibaba", "alibaba-coding-plan", "anthropic", "arcee", "azure-foundry", "bedrock", "copilot", "copilot-acp", "deepseek", "fireworks", "github-copilot", "gemini", "gmi", "huggingface", "kilo", "kilocode", "kimi-coding", "kimi-coding-cn", "kimi-for-coding", "lmstudio", "minimax", "minimax-cn", "minimax-oauth", "moa", "nous", "novita", "nvidia", "ollama-cloud", "openai-api", "openai-codex", "opencode", "opencode-go", "opencode-zen", "openrouter", "stepfun", "tencent-tokenhub", "xai", "xai-oauth", "xiaomi", "zai", "vertex" ]); const HERMES_DYNAMIC_KIMI_PROVIDER_IDS = /* @__PURE__ */ new Set([ "kimi", "kimi-coding", "kimi-for-coding", "moonshot" ]); const HERMES_RETIRED_QWEN_PROVIDER_IDS = /* @__PURE__ */ new Set([ "qwen-cli", "qwen-oauth", "qwen-portal" ]); function normalizeHermesProviderId(provider) { const normalized = normalizeHermesCustomProviderId(provider); return HERMES_PROVIDER_ALIASES[normalized] ?? normalized; } function normalizeHermesCustomProviderId(provider) { const normalized = provider.trim().toLowerCase(); return (normalized.startsWith("custom:") ? normalized.slice(7) : normalized).replaceAll(" ", "-"); } function isRetiredHermesQwenProviderValue(value) { const slash = value.indexOf("/"); const provider = slash > 0 ? value.slice(0, slash) : value; return HERMES_RETIRED_QWEN_PROVIDER_IDS.has(normalizeHermesCustomProviderId(provider)); } function usesRetiredHermesQwenProvider(config) { const model = asOptionalRecord(config.model); return [ normalizeOptionalString(config.provider), typeof config.model === "string" ? config.model : void 0, normalizeOptionalString(model?.provider), normalizeOptionalString(model?.default), normalizeOptionalString(model?.model), normalizeOptionalString(config.default_model), normalizeOptionalString(config.model_name) ].some((value) => value !== void 0 && isRetiredHermesQwenProviderValue(value)); } function readBaseUrl(value) { return value ? normalizeOptionalString(value.base_url) ?? normalizeOptionalString(value.baseUrl) ?? normalizeOptionalString(value.url) ?? normalizeOptionalString(value.api) : void 0; } function readKimiBaseUrl(config, provider, env) { const model = asOptionalRecord(config.model); const selectedProvider = normalizeOptionalString(model?.provider) ?? normalizeOptionalString(config.provider); if (selectedProvider && HERMES_DYNAMIC_KIMI_PROVIDER_IDS.has(normalizeHermesCustomProviderId(selectedProvider))) { const modelBaseUrl = readBaseUrl(model); if (modelBaseUrl) return modelBaseUrl; } const providers = asOptionalRecord(config.providers); for (const [id, value] of Object.entries(providers ?? {})) if (normalizeHermesCustomProviderId(id) === normalizeHermesCustomProviderId(provider) && asOptionalRecord(value)) { const providerBaseUrl = readBaseUrl(asOptionalRecord(value)); if (providerBaseUrl) return providerBaseUrl; } return env.KIMI_BASE_URL?.trim() || void 0; } function resolveHermesKimiProviderId(config, provider, env) { const sourceProvider = normalizeHermesCustomProviderId(provider); if (!HERMES_DYNAMIC_KIMI_PROVIDER_IDS.has(sourceProvider)) return; const baseUrl = readKimiBaseUrl(config, sourceProvider, env); if (baseUrl) { try { const parsed = new URL(baseUrl); const hostname = parsed.hostname.toLowerCase(); const pathname = parsed.pathname.toLowerCase().replace(/\/+$/u, ""); if (hostname === "api.kimi.com" && (pathname === "/coding" || pathname === "/coding/v1")) return "kimi"; if (hostname === "api.moonshot.ai") return "moonshot"; } catch {} return normalizeHermesProviderId(sourceProvider) === "moonshot" ? "moonshot" : "kimi"; } return (env.KIMI_API_KEY?.trim() || env.KIMI_CODING_API_KEY?.trim())?.startsWith("sk-kimi-") ? "kimi" : "moonshot"; } function hasExplicitHermesProvider(config, provider) { const normalized = normalizeHermesCustomProviderId(provider); if (HERMES_CANONICAL_PROVIDER_IDS.has(normalized) || HERMES_RETIRED_QWEN_PROVIDER_IDS.has(normalized)) return false; const providers = config.providers; if (providers && typeof providers === "object" && !Array.isArray(providers) && Object.keys(providers).some((id) => normalizeHermesCustomProviderId(id) === normalized)) return true; return Array.isArray(config.custom_providers) && config.custom_providers.some((entry) => { if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false; const record = entry; const id = normalizeOptionalString(record.name) ?? normalizeOptionalString(record.id); return id ? normalizeHermesCustomProviderId(id) === normalized : false; }); } function resolveHermesConfiguredProviderId(config, provider, env = {}) { if (hasExplicitHermesProvider(config, provider)) return normalizeHermesCustomProviderId(provider); return resolveHermesKimiProviderId(config, provider, env) ?? normalizeHermesProviderId(provider); } function joinHermesProviderModel(config, provider, model, env) { if (!provider) { const slash = model.indexOf("/"); if (slash > 0 && isRetiredHermesQwenProviderValue(model)) return `qwen/${model.slice(slash + 1)}`; return model; } if (provider.trim().toLowerCase() === "auto") { const slash = model.indexOf("/"); return slash > 0 ? `${resolveHermesConfiguredProviderId(config, model.slice(0, slash), env)}/${model.slice(slash + 1)}` : model; } const explicitProvider = hasExplicitHermesProvider(config, provider); const normalizedProvider = resolveHermesConfiguredProviderId(config, provider, env); const slash = model.indexOf("/"); if (slash > 0) { if ((explicitProvider ? normalizeHermesCustomProviderId(model.slice(0, slash)) : resolveHermesConfiguredProviderId(config, model.slice(0, slash), env)) === normalizedProvider) return `${normalizedProvider}/${model.slice(slash + 1)}`; } return model.startsWith(`${normalizedProvider}/`) ? model : `${normalizedProvider}/${model}`; } function resolveHermesModelRef(config, env = {}) { const model = config.model; if (typeof model === "string" && model.trim()) { const rawModel = model.trim(); return joinHermesProviderModel(config, normalizeOptionalString(config.provider), rawModel, env); } if (model && typeof model === "object" && !Array.isArray(model)) { const modelRecord = model; const rawModel = normalizeOptionalString(modelRecord.default) ?? normalizeOptionalString(modelRecord.model); const hasCustomEndpoint = Boolean(normalizeOptionalString(modelRecord.base_url) ?? normalizeOptionalString(modelRecord.baseUrl)); const provider = normalizeOptionalString(modelRecord.provider) ?? (hasCustomEndpoint ? "custom" : void 0); return rawModel ? joinHermesProviderModel(config, provider, rawModel, env) : void 0; } const rootModel = normalizeOptionalString(config.default_model) ?? normalizeOptionalString(config.model_name); const rootProvider = normalizeOptionalString(config.provider); return rootModel ? joinHermesProviderModel(config, rootProvider, rootModel, env) : void 0; } function resolveCurrentModelRef(ctx) { return resolveAgentEffectiveModelPrimary(ctx.config, ctx.targetAgentId ?? resolveDefaultAgentId(ctx.config)); } var ModelApplyAbortError = class extends Error { constructor(status, reason) { super(reason); this.status = status; this.reason = reason; this.name = "ModelApplyAbortError"; } }; async function applyModelItem(ctx, item) { const details = readHermesModelDetails(item); if (!details || item.status !== "planned") return item; try { const configApi = resolveMigrationConfigRuntime(ctx); if (!configApi?.current || !configApi.mutateConfigFile) return hermesItemError(item, HERMES_REASON_CONFIG_RUNTIME_UNAVAILABLE); const agentId = ctx.targetAgentId ?? resolveDefaultAgentId(ctx.config); const currentModel = resolveAgentEffectiveModelPrimary(configApi.current(), agentId); if (currentModel === details.model) return hermesItemSkipped(item, HERMES_REASON_ALREADY_CONFIGURED); if (currentModel && !ctx.overwrite) return hermesItemConflict(item, HERMES_REASON_DEFAULT_MODEL_CONFIGURED); await configApi.mutateConfigFile({ base: "runtime", afterWrite: { mode: "auto" }, mutate(draft) { const mutationModel = resolveAgentEffectiveModelPrimary(draft, agentId); if (mutationModel === details.model) throw new ModelApplyAbortError("skipped", HERMES_REASON_ALREADY_CONFIGURED); if (mutationModel && !ctx.overwrite) throw new ModelApplyAbortError("conflict", HERMES_REASON_DEFAULT_MODEL_CONFIGURED); setAgentEffectiveModelPrimary(draft, agentId, details.model, { forceAgent: Boolean(ctx.targetAgentId) }); } }); return { ...item, status: "migrated" }; } catch (err) { if (err instanceof ModelApplyAbortError) return err.status === "conflict" ? hermesItemConflict(item, err.reason) : hermesItemSkipped(item, err.reason); return hermesItemError(item, err instanceof Error ? err.message : String(err)); } } //#endregion export { resolveHermesConfiguredProviderId as a, resolveCurrentModelRef as i, normalizeHermesCustomProviderId as n, resolveHermesModelRef as o, normalizeHermesProviderId as r, usesRetiredHermesQwenProvider as s, applyModelItem as t };