mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-23 06:41:44 +00:00
refactor: dedupe provider lowercase helpers
This commit is contained in:
@@ -4,6 +4,7 @@ import type {
|
||||
ModelDefinitionConfig,
|
||||
ModelProviderConfig,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
const log = createSubsystemLogger("bedrock-mantle-discovery");
|
||||
|
||||
@@ -145,7 +146,7 @@ const REASONING_PATTERNS = [
|
||||
];
|
||||
|
||||
function inferReasoningSupport(modelId: string): boolean {
|
||||
const lower = modelId.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(modelId);
|
||||
return REASONING_PATTERNS.some((p) => lower.includes(p));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import type {
|
||||
ModelDefinitionConfig,
|
||||
ModelProviderConfig,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveAnthropicVertexRegion } from "./region.js";
|
||||
export const ANTHROPIC_VERTEX_DEFAULT_MODEL_ID = "claude-sonnet-4-6";
|
||||
const ANTHROPIC_VERTEX_DEFAULT_CONTEXT_WINDOW = 1_000_000;
|
||||
@@ -52,7 +53,7 @@ export function buildAnthropicVertexProvider(params?: {
|
||||
}): ModelProviderConfig {
|
||||
const region = resolveAnthropicVertexRegion(params?.env);
|
||||
const baseUrl =
|
||||
region.toLowerCase() === "global"
|
||||
normalizeLowercaseStringOrEmpty(region) === "global"
|
||||
? "https://aiplatform.googleapis.com"
|
||||
: `https://${region}-aiplatform.googleapis.com`;
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export type BraveConfig = {
|
||||
mode?: string;
|
||||
@@ -126,7 +129,8 @@ function normalizeBraveSearchLang(value: string | undefined): string | undefined
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
const canonical = BRAVE_SEARCH_LANG_ALIASES[trimmed.toLowerCase()] ?? trimmed.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
const canonical = BRAVE_SEARCH_LANG_ALIASES[lower] ?? lower;
|
||||
if (!BRAVE_SEARCH_LANG_CODES.has(canonical)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -158,7 +162,7 @@ function normalizeBraveUiLang(value: string | undefined): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
const [, language, region] = match;
|
||||
return `${language.toLowerCase()}-${region.toUpperCase()}`;
|
||||
return `${normalizeLowercaseStringOrEmpty(language)}-${region.toUpperCase()}`;
|
||||
}
|
||||
|
||||
export function resolveBraveConfig(searchConfig?: Record<string, unknown>): BraveConfig {
|
||||
|
||||
@@ -387,7 +387,7 @@ export function buildElevenLabsSpeechProvider(): SpeechProviderPlugin {
|
||||
},
|
||||
resolveTalkOverrides: ({ params }) => {
|
||||
const normalize = trimToUndefined(params.normalize);
|
||||
const language = trimToUndefined(params.language)?.toLowerCase();
|
||||
const language = normalizeLowercaseStringOrEmpty(trimToUndefined(params.language));
|
||||
const latencyTier = asFiniteNumber(params.latencyTier);
|
||||
const voiceSettings = {
|
||||
...(asFiniteNumber(params.speed) == null ? {} : { speed: asFiniteNumber(params.speed) }),
|
||||
|
||||
@@ -220,7 +220,7 @@ async function waitForFalQueueResult(params: {
|
||||
throw new Error(
|
||||
payload.detail?.trim() ||
|
||||
payload.error?.message?.trim() ||
|
||||
`fal video generation ${status.toLowerCase()}`,
|
||||
`fal video generation ${normalizeLowercaseStringOrEmpty(status)}`,
|
||||
);
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export function buildGithubCopilotReplayPolicy(modelId?: string) {
|
||||
return (modelId?.toLowerCase() ?? "").includes("claude")
|
||||
return normalizeLowercaseStringOrEmpty(modelId).includes("claude")
|
||||
? {
|
||||
dropThinkingBlocks: true,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-types";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export const HUGGINGFACE_BASE_URL = "https://router.huggingface.co/v1";
|
||||
export const HUGGINGFACE_POLICY_SUFFIXES = ["cheapest", "fastest"] as const;
|
||||
@@ -91,7 +92,7 @@ export function buildHuggingfaceModelDefinition(
|
||||
}
|
||||
|
||||
function isReasoningModelHeuristic(modelId: string): boolean {
|
||||
const lower = modelId.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(modelId);
|
||||
return (
|
||||
lower.includes("r1") ||
|
||||
lower.includes("reason") ||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { KilocodeModelCatalogEntry } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
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";
|
||||
|
||||
const log = createSubsystemLogger("kilocode-models");
|
||||
|
||||
@@ -77,7 +78,9 @@ function parseModality(entry: GatewayModelEntry): Array<"text" | "image"> {
|
||||
if (!Array.isArray(modalities)) {
|
||||
return ["text"];
|
||||
}
|
||||
const hasImage = modalities.some((m) => typeof m === "string" && m.toLowerCase() === "image");
|
||||
const hasImage = modalities.some(
|
||||
(m) => typeof m === "string" && normalizeLowercaseStringOrEmpty(m) === "image",
|
||||
);
|
||||
return hasImage ? ["text", "image"] : ["text"];
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
fetchWithSsrFGuard,
|
||||
ssrfPolicyFromPrivateNetworkOptIn,
|
||||
} from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { z } from "openclaw/plugin-sdk/zod";
|
||||
|
||||
export type MattermostFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
||||
@@ -344,7 +345,7 @@ export async function createMattermostDirectChannelWithRetry(
|
||||
function isRetryableError(error: Error): boolean {
|
||||
const candidates = collectErrorCandidates(error);
|
||||
const messages = candidates
|
||||
.map((candidate) => readErrorMessage(candidate)?.toLowerCase())
|
||||
.map((candidate) => normalizeLowercaseStringOrEmpty(readErrorMessage(candidate)))
|
||||
.filter((message): message is string => Boolean(message));
|
||||
|
||||
// Retry on 5xx server errors FIRST (before checking 4xx)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import { getMattermostRuntime } from "../runtime.js";
|
||||
import { resolveMattermostAccount, resolveMattermostReplyToMode } from "./accounts.js";
|
||||
import {
|
||||
@@ -1200,7 +1203,11 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {}
|
||||
const mentionRegexes = core.channel.mentions.buildMentionRegexes(cfg, route.agentId);
|
||||
const wasMentioned =
|
||||
kind !== "direct" &&
|
||||
((botUsername ? rawText.toLowerCase().includes(`@${botUsername.toLowerCase()}`) : false) ||
|
||||
((botUsername
|
||||
? normalizeLowercaseStringOrEmpty(rawText).includes(
|
||||
`@${normalizeLowercaseStringOrEmpty(botUsername)}`,
|
||||
)
|
||||
: false) ||
|
||||
core.channel.mentions.matchesMentionPatterns(rawText, mentionRegexes));
|
||||
const pendingBody =
|
||||
rawText ||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { statSync } from "node:fs";
|
||||
import { EdgeTTS } from "node-edge-tts";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export function inferEdgeExtension(outputFormat: string): string {
|
||||
const normalized = outputFormat.toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(outputFormat);
|
||||
if (normalized.includes("webm")) {
|
||||
return ".webm";
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export function isOllamaCompatProvider(model: {
|
||||
}
|
||||
try {
|
||||
const parsed = new URL(model.baseUrl);
|
||||
const hostname = parsed.hostname.toLowerCase();
|
||||
const hostname = normalizeLowercaseStringOrEmpty(parsed.hostname);
|
||||
const isLocalhost =
|
||||
hostname === "localhost" ||
|
||||
hostname === "127.0.0.1" ||
|
||||
|
||||
@@ -2,6 +2,7 @@ import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
getAccessToken,
|
||||
sendC2CMessage,
|
||||
@@ -299,7 +300,7 @@ async function handleImagePayload(ctx: ReplyContext, payload: MediaPayload): Pro
|
||||
try {
|
||||
const fileBuffer = await readStructuredPayloadLocalFile(imageUrl);
|
||||
const base64Data = fileBuffer.toString("base64");
|
||||
const ext = path.extname(imageUrl).toLowerCase();
|
||||
const ext = normalizeLowercaseStringOrEmpty(path.extname(imageUrl));
|
||||
const mimeTypes: Record<string, string> = {
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
postJsonRequest,
|
||||
resolveProviderHttpRequestConfig,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type {
|
||||
GeneratedVideoAsset,
|
||||
VideoGenerationProvider,
|
||||
@@ -212,7 +213,7 @@ async function pollRunwayTask(params: {
|
||||
(typeof payload.failure === "string"
|
||||
? payload.failure
|
||||
: payload.failure?.message
|
||||
)?.trim() || `Runway video generation ${payload.status.toLowerCase()}`,
|
||||
)?.trim() || `Runway video generation ${normalizeLowercaseStringOrEmpty(payload.status)}`,
|
||||
);
|
||||
case "PENDING":
|
||||
case "RUNNING":
|
||||
|
||||
@@ -26,6 +26,7 @@ import { isVerbose, logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/sandbox";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
resolveConfigDir,
|
||||
resolveUserPath,
|
||||
@@ -329,9 +330,7 @@ export function resolveTtsConfig(cfg: OpenClawConfig): ResolvedTtsConfig {
|
||||
mode: raw.mode ?? "final",
|
||||
provider:
|
||||
normalizeConfiguredSpeechProviderId(raw.provider) ??
|
||||
(providerSource === "config"
|
||||
? (normalizeOptionalString(raw.provider)?.toLowerCase() ?? "")
|
||||
: ""),
|
||||
(providerSource === "config" ? (normalizeOptionalLowercaseString(raw.provider) ?? "") : ""),
|
||||
providerSource,
|
||||
summaryModel: normalizeOptionalString(raw.summaryModel),
|
||||
modelOverrides: resolveModelOverridePolicy(raw.modelOverrides),
|
||||
|
||||
@@ -5,7 +5,11 @@ import {
|
||||
fetchWithTimeout,
|
||||
resolveProviderHttpRequestConfig,
|
||||
} from "openclaw/plugin-sdk/provider-http";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export const DEFAULT_VYDRA_BASE_URL = "https://www.vydra.ai/api/v1";
|
||||
export const DEFAULT_VYDRA_IMAGE_MODEL = "grok-imagine";
|
||||
@@ -130,7 +134,7 @@ export function resolveVydraResponseJobId(payload: unknown): string | undefined
|
||||
}
|
||||
|
||||
export function resolveVydraResponseStatus(payload: unknown): string | undefined {
|
||||
return trimToUndefined(asObject(payload)?.status)?.toLowerCase();
|
||||
return normalizeOptionalLowercaseString(trimToUndefined(asObject(payload)?.status));
|
||||
}
|
||||
|
||||
export function resolveVydraErrorMessage(payload: unknown): string | undefined {
|
||||
@@ -187,7 +191,7 @@ export function extractVydraResultUrls(payload: unknown, kind: VydraMediaKind):
|
||||
}
|
||||
|
||||
function inferExtension(kind: VydraMediaKind, mimeType: string): string {
|
||||
const normalized = mimeType.toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(mimeType);
|
||||
if (normalized.includes("jpeg")) {
|
||||
return "jpg";
|
||||
}
|
||||
|
||||
@@ -204,7 +204,9 @@ export function buildXaiCatalogModels(): ModelDefinitionConfig[] {
|
||||
export function resolveXaiCatalogEntry(modelId: string) {
|
||||
const trimmed = modelId.trim();
|
||||
const lower = normalizeOptionalLowercaseString(modelId) ?? "";
|
||||
const exact = XAI_MODEL_CATALOG.find((entry) => entry.id.toLowerCase() === lower);
|
||||
const exact = XAI_MODEL_CATALOG.find(
|
||||
(entry) => normalizeOptionalLowercaseString(entry.id) === lower,
|
||||
);
|
||||
if (exact) {
|
||||
return toModelDefinition(exact);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ function resolveGlm5ForwardCompatModel(
|
||||
ctx: ProviderResolveDynamicModelContext,
|
||||
): ProviderRuntimeModel | undefined {
|
||||
const trimmedModelId = ctx.modelId.trim();
|
||||
if (!trimmedModelId.toLowerCase().startsWith("glm-5")) {
|
||||
if (!normalizeLowercaseStringOrEmpty(trimmedModelId).startsWith("glm-5")) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ import {
|
||||
stripTargetKindPrefix,
|
||||
type ChannelOutboundSessionRouteParams,
|
||||
} from "openclaw/plugin-sdk/core";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
|
||||
export function resolveZaloOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) {
|
||||
const trimmed = stripChannelTargetPrefix(params.target, "zalo", "zl");
|
||||
if (!trimmed) {
|
||||
return null;
|
||||
}
|
||||
const isGroup = trimmed.toLowerCase().startsWith("group:");
|
||||
const isGroup = normalizeLowercaseStringOrEmpty(trimmed).startsWith("group:");
|
||||
const peerId = stripTargetKindPrefix(trimmed);
|
||||
if (!peerId) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user