mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 17:51:22 +00:00
refactor: dedupe provider trimmed readers
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
const log = createSubsystemLogger("chutes-models");
|
||||
|
||||
@@ -507,7 +510,7 @@ function cacheAndReturn(
|
||||
}
|
||||
|
||||
export async function discoverChutesModels(accessToken?: string): Promise<ModelDefinitionConfig[]> {
|
||||
const trimmedKey = accessToken?.trim() ?? "";
|
||||
const trimmedKey = normalizeOptionalString(accessToken) ?? "";
|
||||
const now = Date.now();
|
||||
pruneExpiredCacheEntries(now);
|
||||
const cached = modelCache.get(trimmedKey);
|
||||
@@ -559,7 +562,7 @@ export async function discoverChutesModels(accessToken?: string): Promise<ModelD
|
||||
const models: ModelDefinitionConfig[] = [];
|
||||
|
||||
for (const entry of data) {
|
||||
const id = typeof entry?.id === "string" ? entry.id.trim() : "";
|
||||
const id = normalizeOptionalString(entry?.id) ?? "";
|
||||
if (!id || seen.has(id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ import {
|
||||
wrapWebContent,
|
||||
writeCachedSearchPayload,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
const EXA_SEARCH_ENDPOINT = "https://api.exa.ai/search";
|
||||
const EXA_SEARCH_TYPES = ["auto", "neural", "fast", "deep", "deep-reasoning", "instant"] as const;
|
||||
@@ -105,17 +108,18 @@ function resolveExaDescription(result: ExaSearchResult): string {
|
||||
const highlights = result.highlights;
|
||||
if (Array.isArray(highlights)) {
|
||||
const highlightText = highlights
|
||||
.map((entry) => (typeof entry === "string" ? entry.trim() : ""))
|
||||
.filter(Boolean)
|
||||
.map((entry) => normalizeOptionalString(entry))
|
||||
.filter((entry): entry is string => Boolean(entry))
|
||||
.join("\n");
|
||||
if (highlightText) {
|
||||
return highlightText;
|
||||
}
|
||||
}
|
||||
if (typeof result.summary === "string" && result.summary.trim()) {
|
||||
return result.summary.trim();
|
||||
const summary = normalizeOptionalString(result.summary);
|
||||
if (summary) {
|
||||
return summary;
|
||||
}
|
||||
return typeof result.text === "string" ? result.text.trim() : "";
|
||||
return normalizeOptionalString(result.text) ?? "";
|
||||
}
|
||||
|
||||
function parsePositiveInteger(value: unknown): number | undefined {
|
||||
@@ -558,7 +562,7 @@ function createExaToolDefinition(
|
||||
const title = typeof entry.title === "string" ? entry.title : "";
|
||||
const url = typeof entry.url === "string" ? entry.url : "";
|
||||
const description = resolveExaDescription(entry);
|
||||
const summary = typeof entry.summary === "string" ? entry.summary.trim() : "";
|
||||
const summary = normalizeOptionalString(entry.summary) ?? "";
|
||||
const highlightScores = Array.isArray(entry.highlightScores)
|
||||
? entry.highlightScores.filter(
|
||||
(score): score is number => typeof score === "number" && Number.isFinite(score),
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
wrapWebContent,
|
||||
writeCachedSearchPayload,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { DEFAULT_GOOGLE_API_BASE_URL } from "../api.js";
|
||||
|
||||
const DEFAULT_GEMINI_MODEL = "gemini-2.5-flash";
|
||||
@@ -73,7 +74,7 @@ function resolveGeminiApiKey(gemini?: GeminiConfig): string | undefined {
|
||||
}
|
||||
|
||||
function resolveGeminiModel(gemini?: GeminiConfig): string {
|
||||
const model = typeof gemini?.model === "string" ? gemini.model.trim() : "";
|
||||
const model = normalizeOptionalString(gemini?.model) ?? "";
|
||||
return model || DEFAULT_GEMINI_MODEL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import type { SecretInput } from "openclaw/plugin-sdk/secret-input";
|
||||
import { isRecord } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { applyKimiCodeConfig, KIMI_CODING_MODEL_REF } from "./onboard.js";
|
||||
import { buildKimiCodingProvider } from "./provider-catalog.js";
|
||||
import { KIMI_REPLAY_POLICY } from "./replay-policy.js";
|
||||
@@ -80,8 +80,7 @@ export default definePluginEntry({
|
||||
PROVIDER_ID,
|
||||
);
|
||||
const builtInProvider = buildKimiCodingProvider();
|
||||
const explicitBaseUrl =
|
||||
typeof explicitProvider?.baseUrl === "string" ? explicitProvider.baseUrl.trim() : "";
|
||||
const explicitBaseUrl = normalizeOptionalString(explicitProvider?.baseUrl) ?? "";
|
||||
const explicitHeaders = isRecord(explicitProvider?.headers)
|
||||
? (explicitProvider.headers as Record<string, SecretInput>)
|
||||
: undefined;
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
type WebSearchProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { OLLAMA_DEFAULT_BASE_URL } from "./defaults.js";
|
||||
import {
|
||||
buildOllamaBaseUrlSsrFPolicy,
|
||||
@@ -64,7 +65,7 @@ function resolveOllamaWebSearchApiKey(config?: OpenClawConfig): string | undefin
|
||||
|
||||
function resolveOllamaWebSearchBaseUrl(config?: OpenClawConfig): string {
|
||||
const configuredBaseUrl = config?.models?.providers?.ollama?.baseUrl;
|
||||
if (typeof configuredBaseUrl === "string" && configuredBaseUrl.trim()) {
|
||||
if (normalizeOptionalString(configuredBaseUrl)) {
|
||||
return resolveOllamaApiBase(configuredBaseUrl);
|
||||
}
|
||||
return OLLAMA_DEFAULT_BASE_URL;
|
||||
@@ -73,14 +74,14 @@ function resolveOllamaWebSearchBaseUrl(config?: OpenClawConfig): string {
|
||||
function normalizeOllamaWebSearchResult(
|
||||
result: OllamaWebSearchResult,
|
||||
): { title: string; url: string; content: string } | null {
|
||||
const url = typeof result.url === "string" ? result.url.trim() : "";
|
||||
const url = normalizeOptionalString(result.url) ?? "";
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
title: typeof result.title === "string" ? result.title.trim() : "",
|
||||
title: normalizeOptionalString(result.title) ?? "",
|
||||
url,
|
||||
content: typeof result.content === "string" ? result.content.trim() : "",
|
||||
content: normalizeOptionalString(result.content) ?? "",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,10 @@ import {
|
||||
wrapWebContent,
|
||||
writeCachedSearchPayload,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
const DEFAULT_PERPLEXITY_BASE_URL = "https://openrouter.ai/api/v1";
|
||||
const PERPLEXITY_DIRECT_BASE_URL = "https://api.perplexity.ai";
|
||||
@@ -123,7 +126,7 @@ function resolvePerplexityBaseUrl(
|
||||
authSource: "config" | "perplexity_env" | "openrouter_env" | "none" = "none",
|
||||
configuredKey?: string,
|
||||
): string {
|
||||
const fromConfig = typeof perplexity?.baseUrl === "string" ? perplexity.baseUrl.trim() : "";
|
||||
const fromConfig = normalizeOptionalString(perplexity?.baseUrl) ?? "";
|
||||
if (fromConfig) {
|
||||
return fromConfig;
|
||||
}
|
||||
@@ -142,7 +145,7 @@ function resolvePerplexityBaseUrl(
|
||||
}
|
||||
|
||||
function resolvePerplexityModel(perplexity?: PerplexityConfig): string {
|
||||
const model = typeof perplexity?.model === "string" ? perplexity.model.trim() : "";
|
||||
const model = normalizeOptionalString(perplexity?.model) ?? "";
|
||||
return model || DEFAULT_PERPLEXITY_MODEL;
|
||||
}
|
||||
|
||||
@@ -174,8 +177,7 @@ function resolvePerplexityTransport(perplexity?: PerplexityConfig): {
|
||||
const baseUrl = resolvePerplexityBaseUrl(perplexity, auth.source, auth.apiKey);
|
||||
const model = resolvePerplexityModel(perplexity);
|
||||
const hasLegacyOverride = Boolean(
|
||||
(perplexity?.baseUrl && perplexity.baseUrl.trim()) ||
|
||||
(perplexity?.model && perplexity.model.trim()),
|
||||
normalizeOptionalString(perplexity?.baseUrl) || normalizeOptionalString(perplexity?.model),
|
||||
);
|
||||
return {
|
||||
...auth,
|
||||
@@ -187,8 +189,8 @@ function resolvePerplexityTransport(perplexity?: PerplexityConfig): {
|
||||
}
|
||||
|
||||
function extractPerplexityCitations(data: PerplexitySearchResponse): string[] {
|
||||
const topLevel = (data.citations ?? []).filter(
|
||||
(url): url is string => typeof url === "string" && Boolean(url.trim()),
|
||||
const topLevel = (data.citations ?? []).filter((url): url is string =>
|
||||
Boolean(normalizeOptionalString(url)),
|
||||
);
|
||||
if (topLevel.length > 0) {
|
||||
return [...new Set(topLevel)];
|
||||
@@ -205,8 +207,9 @@ function extractPerplexityCitations(data: PerplexitySearchResponse): string[] {
|
||||
: typeof annotation.url === "string"
|
||||
? annotation.url
|
||||
: undefined;
|
||||
if (url?.trim()) {
|
||||
citations.push(url.trim());
|
||||
const normalizedUrl = normalizeOptionalString(url);
|
||||
if (normalizedUrl) {
|
||||
citations.push(normalizedUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -344,8 +347,8 @@ function resolveRuntimeTransport(params: {
|
||||
perplexity && typeof perplexity === "object" && !Array.isArray(perplexity)
|
||||
? (perplexity as { baseUrl?: string; model?: string })
|
||||
: undefined;
|
||||
const configuredBaseUrl = typeof scoped?.baseUrl === "string" ? scoped.baseUrl.trim() : "";
|
||||
const configuredModel = typeof scoped?.model === "string" ? scoped.model.trim() : "";
|
||||
const configuredBaseUrl = normalizeOptionalString(scoped?.baseUrl) ?? "";
|
||||
const configuredModel = normalizeOptionalString(scoped?.model) ?? "";
|
||||
const baseUrl = (() => {
|
||||
if (configuredBaseUrl) {
|
||||
return configuredBaseUrl;
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
normalizeResolvedSecretInputString,
|
||||
normalizeSecretInput,
|
||||
} from "openclaw/plugin-sdk/secret-input";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export const DEFAULT_TAVILY_BASE_URL = "https://api.tavily.com";
|
||||
export const DEFAULT_TAVILY_SEARCH_TIMEOUT_SECONDS = 30;
|
||||
@@ -52,7 +53,7 @@ export function resolveTavilyApiKey(cfg?: OpenClawConfig): string | undefined {
|
||||
export function resolveTavilyBaseUrl(cfg?: OpenClawConfig): string {
|
||||
const search = resolveTavilySearchConfig(cfg);
|
||||
const configured =
|
||||
(typeof search?.baseUrl === "string" ? search.baseUrl.trim() : "") ||
|
||||
(normalizeOptionalString(search?.baseUrl) ?? "") ||
|
||||
normalizeSecretInput(process.env.TAVILY_BASE_URL) ||
|
||||
"";
|
||||
return configured || DEFAULT_TAVILY_BASE_URL;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
definePluginEntry,
|
||||
fetchWithSsrFGuard,
|
||||
@@ -35,11 +36,9 @@ function resolveOwnershipAgent(config: OpenClawConfig): { id: string; name: stri
|
||||
: [];
|
||||
const selected = list.find((entry) => entry.default === true) ?? list[0];
|
||||
|
||||
const id =
|
||||
typeof selected?.id === "string" && selected.id.trim() ? selected.id.trim() : "unknown";
|
||||
const identityName =
|
||||
typeof selected?.identity?.name === "string" ? selected.identity.name.trim() : "";
|
||||
const fallbackName = typeof selected?.name === "string" ? selected.name.trim() : "";
|
||||
const id = normalizeOptionalString(selected?.id) ?? "unknown";
|
||||
const identityName = normalizeOptionalString(selected?.identity?.name) ?? "";
|
||||
const fallbackName = normalizeOptionalString(selected?.name) ?? "";
|
||||
const name = identityName || fallbackName;
|
||||
|
||||
return { id, name };
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
applyProviderConfigWithModelCatalogPreset,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
buildZaiModelDefinition,
|
||||
resolveZaiBaseUrl,
|
||||
@@ -28,8 +29,7 @@ const ZAI_DEFAULT_MODELS = [
|
||||
|
||||
function resolveZaiPresetBaseUrl(cfg: OpenClawConfig, endpoint?: string): string {
|
||||
const existingProvider = cfg.models?.providers?.zai;
|
||||
const existingBaseUrl =
|
||||
typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl.trim() : "";
|
||||
const existingBaseUrl = normalizeOptionalString(existingProvider?.baseUrl) ?? "";
|
||||
return endpoint ? resolveZaiBaseUrl(endpoint) : existingBaseUrl || resolveZaiBaseUrl();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ function applyZaiPreset(
|
||||
params?: { endpoint?: string; modelId?: string },
|
||||
primaryModelRef?: string,
|
||||
): OpenClawConfig {
|
||||
const modelId = params?.modelId?.trim() || ZAI_DEFAULT_MODEL_ID;
|
||||
const modelId = normalizeOptionalString(params?.modelId) ?? ZAI_DEFAULT_MODEL_ID;
|
||||
const modelRef = `zai/${modelId}`;
|
||||
return applyProviderConfigWithModelCatalogPreset(cfg, {
|
||||
providerId: "zai",
|
||||
@@ -61,7 +61,7 @@ export function applyZaiConfig(
|
||||
cfg: OpenClawConfig,
|
||||
params?: { endpoint?: string; modelId?: string },
|
||||
): OpenClawConfig {
|
||||
const modelId = params?.modelId?.trim() || ZAI_DEFAULT_MODEL_ID;
|
||||
const modelId = normalizeOptionalString(params?.modelId) ?? ZAI_DEFAULT_MODEL_ID;
|
||||
const modelRef = modelId === ZAI_DEFAULT_MODEL_ID ? ZAI_DEFAULT_MODEL_REF : `zai/${modelId}`;
|
||||
return applyZaiPreset(cfg, params, modelRef);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user