diff --git a/extensions/anthropic/cli-shared.ts b/extensions/anthropic/cli-shared.ts index d56cc1979e1..a62948e8bb2 100644 --- a/extensions/anthropic/cli-shared.ts +++ b/extensions/anthropic/cli-shared.ts @@ -1,4 +1,5 @@ import type { CliBackendConfig } from "openclaw/plugin-sdk/cli-backend"; +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; export const CLAUDE_CLI_BACKEND_ID = "claude-cli"; export const CLAUDE_CLI_DEFAULT_MODEL_REF = `${CLAUDE_CLI_BACKEND_ID}/claude-sonnet-4-6`; @@ -92,7 +93,7 @@ const CLAUDE_SETTING_SOURCES_ARG = "--setting-sources"; const CLAUDE_SAFE_SETTING_SOURCES = "user"; export function isClaudeCliProvider(providerId: string): boolean { - return providerId.trim().toLowerCase() === CLAUDE_CLI_BACKEND_ID; + return normalizeOptionalLowercaseString(providerId) === CLAUDE_CLI_BACKEND_ID; } export function normalizeClaudePermissionArgs(args?: string[]): string[] | undefined { diff --git a/extensions/browser/src/browser/session-tab-registry.ts b/extensions/browser/src/browser/session-tab-registry.ts index b81ceac3060..8ecf4ae7a9a 100644 --- a/extensions/browser/src/browser/session-tab-registry.ts +++ b/extensions/browser/src/browser/session-tab-registry.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import { browserCloseTab } from "./client.js"; export type TrackedSessionBrowserTab = { @@ -11,7 +12,7 @@ export type TrackedSessionBrowserTab = { const trackedTabsBySession = new Map>(); function normalizeSessionKey(raw: string): string { - return raw.trim().toLowerCase(); + return normalizeOptionalLowercaseString(raw) ?? ""; } function normalizeTargetId(raw: string): string { @@ -19,11 +20,7 @@ function normalizeTargetId(raw: string): string { } function normalizeProfile(raw?: string): string | undefined { - if (!raw) { - return undefined; - } - const trimmed = raw.trim(); - return trimmed ? trimmed.toLowerCase() : undefined; + return normalizeOptionalLowercaseString(raw); } function normalizeBaseUrl(raw?: string): string | undefined { diff --git a/extensions/discord/src/directory-live.ts b/extensions/discord/src/directory-live.ts index 9e1bd221612..071a613ca97 100644 --- a/extensions/discord/src/directory-live.ts +++ b/extensions/discord/src/directory-live.ts @@ -2,6 +2,7 @@ import type { ChannelDirectoryEntry, DirectoryConfigParams, } from "openclaw/plugin-sdk/directory-runtime"; +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import { resolveDiscordAccount } from "./accounts.js"; import { fetchDiscord } from "./api.js"; import { rememberDiscordDirectoryUser } from "./directory-cache.js"; @@ -15,7 +16,7 @@ type DiscordChannel = { id: string; name?: string | null }; type DiscordDirectoryAccess = { token: string; query: string; accountId: string }; function normalizeQuery(value?: string | null): string { - return value?.trim().toLowerCase() ?? ""; + return normalizeOptionalLowercaseString(value) ?? ""; } function buildUserRank(user: DiscordUser): number { diff --git a/extensions/feishu/src/card-ux-launcher.ts b/extensions/feishu/src/card-ux-launcher.ts index e72cea82c05..015572cd6b6 100644 --- a/extensions/feishu/src/card-ux-launcher.ts +++ b/extensions/feishu/src/card-ux-launcher.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import type { ClawdbotConfig, RuntimeEnv } from "../runtime-api.js"; import { createFeishuCardInteractionEnvelope } from "./card-interaction.js"; import { FEISHU_APPROVAL_REQUEST_ACTION } from "./card-ux-approval.js"; @@ -9,7 +10,7 @@ export const FEISHU_QUICK_ACTION_CARD_TTL_MS = 10 * 60_000; const QUICK_ACTION_MENU_KEYS = new Set(["quick-actions", "quick_actions", "launcher"]); export function isFeishuQuickActionMenuEventKey(eventKey: string): boolean { - return QUICK_ACTION_MENU_KEYS.has(eventKey.trim().toLowerCase()); + return QUICK_ACTION_MENU_KEYS.has(normalizeOptionalLowercaseString(eventKey) ?? ""); } export function createQuickActionLauncherCard(params: { diff --git a/extensions/google/provider-models.ts b/extensions/google/provider-models.ts index e90f0178f35..8e380da773a 100644 --- a/extensions/google/provider-models.ts +++ b/extensions/google/provider-models.ts @@ -3,6 +3,7 @@ import type { ProviderRuntimeModel, } from "openclaw/plugin-sdk/plugin-entry"; import { cloneFirstTemplateModel } from "openclaw/plugin-sdk/provider-model-shared"; +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; const GOOGLE_GEMINI_CLI_PROVIDER_ID = "google-gemini-cli"; const GEMINI_2_5_PRO_PREFIX = "gemini-2.5-pro"; @@ -54,7 +55,7 @@ function cloneGoogleTemplateModel(params: { } function isGoogleGeminiCliProvider(providerId: string): boolean { - return providerId.trim().toLowerCase() === GOOGLE_GEMINI_CLI_PROVIDER_ID; + return normalizeOptionalLowercaseString(providerId) === GOOGLE_GEMINI_CLI_PROVIDER_ID; } function templateIdsForProvider( diff --git a/extensions/matrix/src/resolve-targets.ts b/extensions/matrix/src/resolve-targets.ts index 4d2f7843006..4343646915c 100644 --- a/extensions/matrix/src/resolve-targets.ts +++ b/extensions/matrix/src/resolve-targets.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js"; import { isMatrixQualifiedUserId, normalizeMatrixMessagingTarget } from "./matrix/target-ids.js"; import type { @@ -8,7 +9,7 @@ import type { } from "./runtime-api.js"; function normalizeLookupQuery(query: string): string { - return query.trim().toLowerCase(); + return normalizeOptionalLowercaseString(query) ?? ""; } function findExactDirectoryMatches( @@ -20,9 +21,9 @@ function findExactDirectoryMatches( return []; } return matches.filter((match) => { - const id = match.id.trim().toLowerCase(); - const name = match.name?.trim().toLowerCase(); - const handle = match.handle?.trim().toLowerCase(); + const id = normalizeOptionalLowercaseString(match.id); + const name = normalizeOptionalLowercaseString(match.name); + const handle = normalizeOptionalLowercaseString(match.handle); return normalized === id || normalized === name || normalized === handle; }); } diff --git a/extensions/telegram/src/command-config.ts b/extensions/telegram/src/command-config.ts index e7c316791d7..7ee06001c8d 100644 --- a/extensions/telegram/src/command-config.ts +++ b/extensions/telegram/src/command-config.ts @@ -1,3 +1,5 @@ +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; + export const TELEGRAM_COMMAND_NAME_PATTERN = /^[a-z0-9_]{1,32}$/; export type TelegramCustomCommandInput = { @@ -17,7 +19,7 @@ export function normalizeTelegramCommandName(value: string): string { return ""; } const withoutSlash = trimmed.startsWith("/") ? trimmed.slice(1) : trimmed; - return withoutSlash.trim().toLowerCase().replace(/-/g, "_"); + return (normalizeOptionalLowercaseString(withoutSlash) ?? "").replace(/-/g, "_"); } export function normalizeTelegramCommandDescription(value: string): string { diff --git a/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts b/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts index 46287758c8b..83c27548c78 100644 --- a/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts +++ b/extensions/whatsapp/src/auto-reply/heartbeat-runner.ts @@ -1,3 +1,4 @@ +import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime"; import { newConnectionId } from "../reconnect.js"; import { DEFAULT_HEARTBEAT_ACK_MAX_CHARS, @@ -31,7 +32,7 @@ import { getSessionSnapshot } from "./session-snapshot.js"; function resolveDefaultAgentIdFromConfig(cfg: ReturnType): string { const agents = cfg.agents?.list ?? []; const chosen = agents.find((agent) => agent?.default)?.id ?? agents[0]?.id ?? "main"; - return chosen.trim().toLowerCase() || "main"; + return normalizeOptionalLowercaseString(chosen) ?? "main"; } export async function runWebHeartbeatOnce(opts: {