




























@@ -58,6 +58,8 @@ const WRAPPER_PROVIDERS = new Set([
5858"openrouter",
5959"vercel-ai-gateway",
6060]);
61+const LOCAL_MODEL_PROVIDER_APIS = new Set(["ollama"]);
62+const LOCAL_MODEL_PROVIDER_IDS = new Set(["lmstudio", "ollama", "sglang", "vllm"]);
6163const log = createSubsystemLogger("gateway").child("model-pricing");
62646365let refreshTimer: ReturnType<typeof setTimeout> | null = null;
@@ -422,6 +424,60 @@ function addConfiguredWebSearchPluginModels(params: {
422424}
423425}
424426427+function isPrivateOrLoopbackHost(hostname: string): boolean {
428+const host = hostname
429+.trim()
430+.toLowerCase()
431+.replace(/^\[|\]$/g, "");
432+if (
433+host === "localhost" ||
434+host === "localhost.localdomain" ||
435+host.endsWith(".localhost") ||
436+host.endsWith(".local")
437+) {
438+return true;
439+}
440+if (host === "::1" || host === "0:0:0:0:0:0:0:1" || host.startsWith("fe80:")) {
441+return true;
442+}
443+if (host.startsWith("fc") || host.startsWith("fd")) {
444+return true;
445+}
446+if (host.startsWith("127.") || host.startsWith("10.") || host.startsWith("192.168.")) {
447+return true;
448+}
449+return /^172\.(1[6-9]|2\d|3[0-1])\./u.test(host) || host.startsWith("169.254.");
450+}
451+452+function isPrivateOrLoopbackBaseUrl(baseUrl: string | undefined): boolean {
453+if (!baseUrl) {
454+return false;
455+}
456+try {
457+return isPrivateOrLoopbackHost(new URL(baseUrl).hostname);
458+} catch {
459+return false;
460+}
461+}
462+463+function shouldFetchExternalPricingForRef(config: OpenClawConfig, ref: ModelRef): boolean {
464+const providerConfig = config.models?.providers?.[ref.provider];
465+if (providerConfig?.api && LOCAL_MODEL_PROVIDER_APIS.has(providerConfig.api)) {
466+return false;
467+}
468+if (LOCAL_MODEL_PROVIDER_IDS.has(ref.provider)) {
469+return false;
470+}
471+if (isPrivateOrLoopbackBaseUrl(providerConfig?.baseUrl)) {
472+return false;
473+}
474+return true;
475+}
476+477+function filterExternalPricingRefs(config: OpenClawConfig, refs: ModelRef[]): ModelRef[] {
478+return refs.filter((ref) => shouldFetchExternalPricingForRef(config, ref));
479+}
480+425481export function collectConfiguredModelPricingRefs(config: OpenClawConfig): ModelRef[] {
426482const refs = new Map<string, ModelRef>();
427483const aliasIndex = buildModelAliasIndex({
@@ -547,7 +603,10 @@ export async function refreshGatewayModelPricingCache(params: {
547603}
548604const fetchImpl = params.fetchImpl ?? fetch;
549605inFlightRefresh = (async () => {
550-const refs = collectConfiguredModelPricingRefs(params.config);
606+const refs = filterExternalPricingRefs(
607+params.config,
608+collectConfiguredModelPricingRefs(params.config),
609+);
551610if (refs.length === 0) {
552611replaceGatewayModelPricingCache(new Map());
553612clearRefreshTimer();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。