From ad605052bfc89da0a6953be24b28313477b4a218 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 14:23:05 +0100 Subject: [PATCH] refactor: dedupe provider lowercase helpers --- extensions/bluebubbles/src/monitor-processing.ts | 3 ++- extensions/discord/src/proxy-fetch.ts | 3 ++- extensions/duckduckgo/src/config.ts | 3 ++- extensions/fal/image-generation-provider.ts | 12 ++++++++---- extensions/fal/video-generation-provider.ts | 3 ++- extensions/microsoft-foundry/shared.ts | 3 ++- extensions/nextcloud-talk/src/setup-core.ts | 5 +++-- extensions/qa-lab/src/bus-queries.ts | 3 ++- 8 files changed, 23 insertions(+), 12 deletions(-) diff --git a/extensions/bluebubbles/src/monitor-processing.ts b/extensions/bluebubbles/src/monitor-processing.ts index 30ad41045c0..84be916b8ec 100644 --- a/extensions/bluebubbles/src/monitor-processing.ts +++ b/extensions/bluebubbles/src/monitor-processing.ts @@ -5,6 +5,7 @@ import { } from "openclaw/plugin-sdk/reply-payload"; import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime"; import { + normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, } from "openclaw/plugin-sdk/text-runtime"; @@ -319,7 +320,7 @@ function consumePendingOutboundMessageId(params: { }): PendingOutboundMessageId | null { prunePendingOutboundMessageIds(); const bodyNorm = normalizeSnippet(params.body); - const isMediaBody = params.body.trim().toLowerCase().startsWith("): SsrFPoli } function matchesTrustedHostSuffix(hostname: string, trustedSuffix: string): boolean { - const normalizedHost = hostname.trim().toLowerCase(); - const normalizedSuffix = trustedSuffix.trim().toLowerCase(); + const normalizedHost = normalizeLowercaseStringOrEmpty(hostname); + const normalizedSuffix = normalizeLowercaseStringOrEmpty(trustedSuffix); return normalizedHost === normalizedSuffix || normalizedHost.endsWith(`.${normalizedSuffix}`); } @@ -97,7 +101,7 @@ function resolveFalNetworkPolicy(params: { return {}; } - const hostSuffix = parsedBaseUrl.hostname.trim().toLowerCase(); + const hostSuffix = normalizeLowercaseStringOrEmpty(parsedBaseUrl.hostname); if (!hostSuffix || !params.allowPrivateNetwork) { return {}; } @@ -241,7 +245,7 @@ function toDataUri(buffer: Buffer, mimeType: string): string { } function fileExtensionForMimeType(mimeType: string | undefined): string { - const normalized = mimeType?.toLowerCase().trim(); + const normalized = normalizeOptionalLowercaseString(mimeType); if (!normalized) { return "png"; } diff --git a/extensions/fal/video-generation-provider.ts b/extensions/fal/video-generation-provider.ts index 52feb3e25eb..a7642a4dc57 100644 --- a/extensions/fal/video-generation-provider.ts +++ b/extensions/fal/video-generation-provider.ts @@ -9,6 +9,7 @@ import { type SsrFPolicy, ssrfPolicyFromDangerouslyAllowPrivateNetwork, } from "openclaw/plugin-sdk/ssrf-runtime"; +import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime"; import type { GeneratedVideoAsset, VideoGenerationProvider, @@ -107,7 +108,7 @@ function resolveFalQueueBaseUrl(baseUrl: string): string { } function isFalMiniMaxLiveModel(model: string): boolean { - return model.trim().toLowerCase() === DEFAULT_FAL_VIDEO_MODEL; + return normalizeLowercaseStringOrEmpty(model) === DEFAULT_FAL_VIDEO_MODEL; } function buildFalVideoRequestBody(params: { diff --git a/extensions/microsoft-foundry/shared.ts b/extensions/microsoft-foundry/shared.ts index 9038106a139..477024934b8 100644 --- a/extensions/microsoft-foundry/shared.ts +++ b/extensions/microsoft-foundry/shared.ts @@ -5,6 +5,7 @@ import { type SecretInput, } from "openclaw/plugin-sdk/provider-auth"; import type { ModelApi, ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; +import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime"; export const PROVIDER_ID = "microsoft-foundry"; export const DEFAULT_API = "openai-completions"; @@ -111,7 +112,7 @@ type FoundryConfigShape = { }; export function normalizeFoundryModelName(value?: string | null): string | undefined { - const trimmed = typeof value === "string" ? value.trim().toLowerCase() : ""; + const trimmed = normalizeLowercaseStringOrEmpty(value); return trimmed || undefined; } diff --git a/extensions/nextcloud-talk/src/setup-core.ts b/extensions/nextcloud-talk/src/setup-core.ts index d35c63ca346..fd1948f1a2e 100644 --- a/extensions/nextcloud-talk/src/setup-core.ts +++ b/extensions/nextcloud-talk/src/setup-core.ts @@ -10,6 +10,7 @@ import { type WizardPrompter, } from "openclaw/plugin-sdk/setup-runtime"; import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools"; +import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime"; import { applyAccountNameToChannelSection, patchScopedAccountConfig } from "../runtime-api.js"; import { resolveDefaultNextcloudTalkAccountId, resolveNextcloudTalkAccount } from "./accounts.js"; import type { CoreConfig } from "./types.js"; @@ -124,14 +125,14 @@ async function promptNextcloudTalkAllowFrom(params: { parseEntries: (raw) => ({ entries: String(raw) .split(/[\n,;]+/g) - .map((value) => value.trim().toLowerCase()) + .map(normalizeLowercaseStringOrEmpty) .filter(Boolean), }), getExistingAllowFrom: ({ cfg, accountId }) => resolveNextcloudTalkAccount({ cfg, accountId }).config.allowFrom ?? [], mergeEntries: ({ existing, parsed }) => mergeAllowFromEntries( - existing.map((value) => String(value).trim().toLowerCase()), + existing.map((value) => normalizeLowercaseStringOrEmpty(String(value))), parsed, ), applyAllowFrom: ({ cfg, accountId, allowFrom }) => diff --git a/extensions/qa-lab/src/bus-queries.ts b/extensions/qa-lab/src/bus-queries.ts index ec6d449dab3..2ca1fe5527a 100644 --- a/extensions/qa-lab/src/bus-queries.ts +++ b/extensions/qa-lab/src/bus-queries.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import type { QaBusConversation, QaBusEvent, @@ -103,7 +104,7 @@ export function searchQaBusMessages(params: { }) { const accountId = normalizeAccountId(params.input.accountId); const limit = Math.max(1, Math.min(params.input.limit ?? 20, 100)); - const query = params.input.query?.trim().toLowerCase(); + const query = normalizeOptionalLowercaseString(params.input.query); return Array.from(params.messages.values()) .filter((message) => message.accountId === accountId) .filter((message) =>