mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
refactor: dedupe provider lowercase helpers
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
type OpenClawConfig,
|
||||
type ProviderAuthResult,
|
||||
} from "openclaw/plugin-sdk/provider-auth";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
readClaudeCliCredentialsForSetup,
|
||||
readClaudeCliCredentialsForSetupNonInteractive,
|
||||
@@ -19,11 +20,11 @@ type ClaudeCliCredential = NonNullable<ReturnType<typeof readClaudeCliCredential
|
||||
|
||||
function toClaudeCliModelRef(raw: string): string | null {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed.toLowerCase().startsWith("anthropic/")) {
|
||||
if (!normalizeLowercaseStringOrEmpty(trimmed).startsWith("anthropic/")) {
|
||||
return null;
|
||||
}
|
||||
const modelId = trimmed.slice("anthropic/".length).trim();
|
||||
if (!modelId.toLowerCase().startsWith("claude-")) {
|
||||
if (!normalizeLowercaseStringOrEmpty(modelId).startsWith("claude-")) {
|
||||
return null;
|
||||
}
|
||||
return `claude-cli/${modelId}`;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { CLAUDE_CLI_BACKEND_ID, CLAUDE_CLI_DEFAULT_ALLOWLIST_REFS } from "./cli-shared.js";
|
||||
|
||||
const ANTHROPIC_PROVIDER_API = "anthropic-messages";
|
||||
@@ -84,7 +85,7 @@ function resolveAnthropicPrimaryModelRef(raw?: string): string | null {
|
||||
if (!trimmed) {
|
||||
return null;
|
||||
}
|
||||
const aliasKey = trimmed.toLowerCase();
|
||||
const aliasKey = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
if (aliasKey === "opus") {
|
||||
return "anthropic/claude-opus-4-6";
|
||||
}
|
||||
@@ -124,7 +125,7 @@ function isAnthropicCacheRetentionTarget(
|
||||
parsed &&
|
||||
(parsed.provider === "anthropic" ||
|
||||
(parsed.provider === "amazon-bedrock" &&
|
||||
parsed.model.toLowerCase().includes("anthropic.claude"))),
|
||||
normalizeLowercaseStringOrEmpty(parsed.model).includes("anthropic.claude"))),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,7 @@ import {
|
||||
streamWithPayloadPatch,
|
||||
} from "openclaw/plugin-sdk/provider-stream-shared";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
readStringValue,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty, readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
const log = createSubsystemLogger("anthropic-stream");
|
||||
|
||||
@@ -50,7 +46,9 @@ function mergeAnthropicBetaHeader(
|
||||
betas: string[],
|
||||
): Record<string, string> {
|
||||
const merged = { ...headers };
|
||||
const existingKey = Object.keys(merged).find((key) => key.toLowerCase() === "anthropic-beta");
|
||||
const existingKey = Object.keys(merged).find(
|
||||
(key) => normalizeLowercaseStringOrEmpty(key) === "anthropic-beta",
|
||||
);
|
||||
const existing = existingKey ? parseHeaderList(merged[existingKey]) : [];
|
||||
const values = Array.from(new Set([...existing, ...betas]));
|
||||
const key = existingKey ?? "anthropic-beta";
|
||||
@@ -73,7 +71,7 @@ function normalizeFastMode(raw?: string | boolean | null): boolean | undefined {
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
const key = raw.toLowerCase();
|
||||
const key = normalizeLowercaseStringOrEmpty(raw);
|
||||
if (["off", "false", "no", "0", "disable", "disabled", "normal"].includes(key)) {
|
||||
return false;
|
||||
}
|
||||
@@ -87,7 +85,7 @@ function normalizeAnthropicServiceTier(value: unknown): AnthropicServiceTier | u
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = normalizeOptionalString(value)?.toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(value);
|
||||
if (normalized === "auto" || normalized === "standard_only") {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import path from "node:path";
|
||||
import { fileURLToPath, URL } from "node:url";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
function isLocalFileUrlHost(hostname: string): boolean {
|
||||
return hostname === "" || hostname.toLowerCase() === "localhost";
|
||||
const normalized = normalizeLowercaseStringOrEmpty(hostname);
|
||||
return normalized === "" || normalized === "localhost";
|
||||
}
|
||||
|
||||
function assertNoWindowsNetworkPath(filePath: string, label = "Path"): void {
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
||||
import { safeEqualSecret } from "openclaw/plugin-sdk/browser-security-runtime";
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { createBlueBubblesDebounceRegistry } from "./monitor-debounce.js";
|
||||
import {
|
||||
asRecord,
|
||||
@@ -110,7 +111,7 @@ function normalizeAuthToken(raw: string): string {
|
||||
if (!value) {
|
||||
return "";
|
||||
}
|
||||
if (value.toLowerCase().startsWith("bearer ")) {
|
||||
if (normalizeLowercaseStringOrEmpty(value).startsWith("bearer ")) {
|
||||
return value.slice("bearer ".length).trim();
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { ImageGenerationProvider } from "openclaw/plugin-sdk/image-generati
|
||||
import { isProviderApiKeyConfigured } from "openclaw/plugin-sdk/provider-auth";
|
||||
import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime";
|
||||
import { assertOkOrThrowHttpError, postJsonRequest } from "openclaw/plugin-sdk/provider-http";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { normalizeGoogleModelId, resolveGoogleGenerativeAiHttpRequestConfig } from "./api.js";
|
||||
|
||||
const DEFAULT_GOOGLE_IMAGE_MODEL = "gemini-3.1-flash-image-preview";
|
||||
@@ -57,7 +58,7 @@ function mapSizeToImageConfig(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const normalized = trimmed.toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
const mapping = new Map<string, string>([
|
||||
["1024x1024", "1:1"],
|
||||
["1024x1536", "2:3"],
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
resolveLoggerBackedRuntime,
|
||||
safeParseJsonWithSchema,
|
||||
} from "openclaw/plugin-sdk/extension-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
WEBHOOK_RATE_LIMIT_DEFAULTS,
|
||||
@@ -72,7 +73,7 @@ function formatError(err: unknown): string {
|
||||
|
||||
function normalizeOrigin(value: string): string | null {
|
||||
try {
|
||||
return new URL(value).origin.toLowerCase();
|
||||
return normalizeLowercaseStringOrEmpty(new URL(value).origin);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export function stripNextcloudTalkTargetPrefix(raw: string): string | undefined {
|
||||
const trimmed = raw.trim();
|
||||
if (!trimmed) {
|
||||
@@ -27,7 +29,7 @@ export function stripNextcloudTalkTargetPrefix(raw: string): string | undefined
|
||||
|
||||
export function normalizeNextcloudTalkMessagingTarget(raw: string): string | undefined {
|
||||
const normalized = stripNextcloudTalkTargetPrefix(raw);
|
||||
return normalized ? `nextcloud-talk:${normalized}`.toLowerCase() : undefined;
|
||||
return normalized ? normalizeLowercaseStringOrEmpty(`nextcloud-talk:${normalized}`) : undefined;
|
||||
}
|
||||
|
||||
export function looksLikeNextcloudTalkTargetId(raw: string): boolean {
|
||||
|
||||
@@ -5,7 +5,10 @@ import { applyAgentDefaultModelPrimary } from "openclaw/plugin-sdk/provider-onbo
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
|
||||
import { WizardCancelledError, type WizardPrompter } from "openclaw/plugin-sdk/setup";
|
||||
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import { OLLAMA_DEFAULT_BASE_URL, OLLAMA_DEFAULT_MODEL } from "./defaults.js";
|
||||
import {
|
||||
buildOllamaBaseUrlSsrFPolicy,
|
||||
@@ -42,7 +45,7 @@ function normalizeOllamaModelName(value: string | undefined): string | undefined
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
if (trimmed.toLowerCase().startsWith("ollama/")) {
|
||||
if (normalizeLowercaseStringOrEmpty(trimmed).startsWith("ollama/")) {
|
||||
const normalized = trimmed.slice("ollama/".length).trim();
|
||||
return normalized || undefined;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ import type {
|
||||
SpeechProviderOverrides,
|
||||
SpeechProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/speech";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
asFiniteNumber,
|
||||
asObjectRecord,
|
||||
@@ -44,7 +48,7 @@ type OpenAITtsProviderOverrides = {
|
||||
function normalizeOpenAISpeechResponseFormat(
|
||||
value: unknown,
|
||||
): OpenAiSpeechResponseFormat | undefined {
|
||||
const next = trimToUndefined(typeof value === "string" ? value : undefined)?.toLowerCase();
|
||||
const next = normalizeOptionalLowercaseString(value);
|
||||
if (!next) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -58,7 +62,7 @@ function normalizeOpenAISpeechResponseFormat(
|
||||
|
||||
function isGroqSpeechBaseUrl(baseUrl: string): boolean {
|
||||
try {
|
||||
const hostname = new URL(baseUrl).hostname.toLowerCase();
|
||||
const hostname = normalizeLowercaseStringOrEmpty(new URL(baseUrl).hostname);
|
||||
return hostname === "groq.com" || hostname.endsWith(".groq.com");
|
||||
} catch {
|
||||
return false;
|
||||
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
wrapWebContent,
|
||||
writeCachedSearchPayload,
|
||||
} from "openclaw/plugin-sdk/provider-web-search";
|
||||
import { normalizeLowercaseStringOrEmpty } 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";
|
||||
@@ -85,7 +86,7 @@ function inferPerplexityBaseUrlFromApiKey(apiKey?: string): PerplexityBaseUrlHin
|
||||
if (!apiKey) {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = apiKey.toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(apiKey);
|
||||
if (PERPLEXITY_KEY_PREFIXES.some((prefix) => normalized.startsWith(prefix))) {
|
||||
return "direct";
|
||||
}
|
||||
@@ -147,7 +148,9 @@ function resolvePerplexityModel(perplexity?: PerplexityConfig): string {
|
||||
|
||||
function isDirectPerplexityBaseUrl(baseUrl: string): boolean {
|
||||
try {
|
||||
return new URL(baseUrl.trim()).hostname.toLowerCase() === "api.perplexity.ai";
|
||||
return (
|
||||
normalizeLowercaseStringOrEmpty(new URL(baseUrl.trim()).hostname) === "api.perplexity.ai"
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
type ProviderCatalogContext,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
applyStepFunPlanConfig,
|
||||
applyStepFunPlanConfigCn,
|
||||
@@ -38,7 +39,7 @@ function inferRegionFromBaseUrl(baseUrl: string | undefined): StepFunRegion | un
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
const host = new URL(baseUrl).hostname.toLowerCase();
|
||||
const host = normalizeLowercaseStringOrEmpty(new URL(baseUrl).hostname);
|
||||
if (host === "api.stepfun.com") {
|
||||
return "cn";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveProviderReasoningOutputModeWithPlugin } from "../plugins/provider-runtime.js";
|
||||
import type { ProviderRuntimeModel } from "../plugins/types.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
|
||||
const BUILTIN_REASONING_OUTPUT_MODES = {
|
||||
"google-generative-ai": "tagged",
|
||||
@@ -25,7 +28,7 @@ export function resolveReasoningOutputMode(params: {
|
||||
return "native";
|
||||
}
|
||||
|
||||
const normalized = provider.toLowerCase();
|
||||
const normalized = normalizeOptionalLowercaseString(provider) ?? "";
|
||||
const pluginMode = resolveProviderReasoningOutputModeWithPlugin({
|
||||
provider,
|
||||
config: params.config,
|
||||
|
||||
Reference in New Issue
Block a user