Skip to content

Commit e0ad3e7

Browse files
committed
refactor: dedupe normalization lowercase helpers
1 parent fa82193 commit e0ad3e7

11 files changed

Lines changed: 29 additions & 19 deletions

File tree

extensions/comfy/workflow-runtime.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function resolveComfyNetworkPolicy(params: {
226226
return {};
227227
}
228228

229-
const hostname = normalizeOptionalString(parsed.hostname)?.toLowerCase() ?? "";
229+
const hostname = normalizeOptionalLowercaseString(parsed.hostname) ?? "";
230230
if (!hostname || !params.allowPrivateNetwork || !isPrivateOrLoopbackHost(hostname)) {
231231
return {};
232232
}

extensions/discord/src/monitor/allow-list.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
type ChannelMatchSource,
88
} from "openclaw/plugin-sdk/channel-targets";
99
import { evaluateGroupRouteAccessForPolicy } from "openclaw/plugin-sdk/group-access";
10+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
1011
import { formatDiscordUserTag } from "./format.js";
1112

1213
export type DiscordAllowList = {
@@ -84,9 +85,7 @@ export function normalizeDiscordAllowList(raw: string[] | undefined, prefixes: s
8485
}
8586

8687
export function normalizeDiscordSlug(value: string) {
87-
return value
88-
.trim()
89-
.toLowerCase()
88+
return normalizeLowercaseStringOrEmpty(value)
9089
.replace(/^#/, "")
9190
.replace(/[^a-z0-9]+/g, "-")
9291
.replace(/^-+|-+$/g, "");

extensions/discord/src/send.guild.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
RESTPostAPIGuildScheduledEventJSONBody,
88
} from "discord-api-types/v10";
99
import { Routes } from "discord-api-types/v10";
10+
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
1011
import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
1112
import { resolveDiscordRest } from "./send.shared.js";
1213
import type {
@@ -89,7 +90,7 @@ export async function resolveEventCoverImage(
8990
const media = await loadWebMediaRaw(imageUrl, DISCORD_MAX_EVENT_COVER_BYTES, {
9091
localRoots: opts?.localRoots,
9192
});
92-
const contentType = media.contentType?.toLowerCase();
93+
const contentType = normalizeOptionalLowercaseString(media.contentType);
9394
if (!contentType || !ALLOWED_EVENT_COVER_TYPES.has(contentType)) {
9495
throw new Error(
9596
`Discord event cover images must be PNG, JPG, or GIF (got ${contentType ?? "unknown"})`,

extensions/memory-lancedb/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type * as LanceDB from "@lancedb/lancedb";
1111
import { Type } from "@sinclair/typebox";
1212
import OpenAI from "openai";
1313
import { ensureGlobalUndiciEnvProxyDispatcher } from "openclaw/plugin-sdk/runtime-env";
14+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
1415
import { definePluginEntry, type OpenClawPluginApi } from "./api.js";
1516
import {
1617
DEFAULT_CAPTURE_MAX_CHARS,
@@ -259,7 +260,7 @@ export function shouldCapture(text: string, options?: { maxChars?: number }): bo
259260
}
260261

261262
export function detectCategory(text: string): MemoryCategory {
262-
const lower = text.toLowerCase();
263+
const lower = normalizeLowercaseStringOrEmpty(text);
263264
if (/prefer|radši|like|love|hate|want/i.test(lower)) {
264265
return "preference";
265266
}

extensions/msteams/src/directory.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
listDirectoryEntriesFromSources,
55
} from "openclaw/plugin-sdk/directory-runtime";
66
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
7+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
78
import type { ChannelPlugin } from "./channel-api.js";
89
import { normalizeMSTeamsMessagingTarget } from "./resolve-allowlist.js";
910
import { resolveMSTeamsCredentials } from "./token.js";
@@ -33,7 +34,7 @@ export const msteamsDirectoryAdapter: NonNullable<ChannelPlugin["directory"]> =
3334
limit,
3435
normalizeId: (raw) => {
3536
const normalized = normalizeMSTeamsMessagingTarget(raw) ?? raw;
36-
const lowered = normalized.toLowerCase();
37+
const lowered = normalizeLowercaseStringOrEmpty(normalized);
3738
if (lowered.startsWith("user:") || lowered.startsWith("conversation:")) {
3839
return normalized;
3940
}

extensions/qa-lab/src/discovery-eval.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
2+
13
const REQUIRED_DISCOVERY_REFS = [
24
"repo/qa/seed-scenarios.json",
35
"repo/qa/QA_KICKOFF_TASK.md",
46
"repo/extensions/qa-lab/src/suite.ts",
57
"repo/docs/help/testing.md",
68
] as const;
79

10+
const REQUIRED_DISCOVERY_REFS_LOWER = REQUIRED_DISCOVERY_REFS.map(normalizeLowercaseStringOrEmpty);
11+
812
const DISCOVERY_SCOPE_LEAK_PHRASES = [
913
"all mandatory scenarios",
1014
"final qa tally",
@@ -15,8 +19,8 @@ const DISCOVERY_SCOPE_LEAK_PHRASES = [
1519
] as const;
1620

1721
function confirmsDiscoveryFileRead(text: string) {
18-
const lower = text.toLowerCase();
19-
const mentionsAllRefs = REQUIRED_DISCOVERY_REFS.every((ref) => lower.includes(ref.toLowerCase()));
22+
const lower = normalizeLowercaseStringOrEmpty(text);
23+
const mentionsAllRefs = REQUIRED_DISCOVERY_REFS_LOWER.every((ref) => lower.includes(ref));
2024
const confirmsRead =
2125
/(?:read|retrieved|inspected|loaded|accessed|digested)\s+all\s+(?:four|4)\s+(?:(?:requested|required|mandated|seeded)\s+)?files/.test(
2226
lower,
@@ -29,7 +33,7 @@ function confirmsDiscoveryFileRead(text: string) {
2933
}
3034

3135
export function hasDiscoveryLabels(text: string) {
32-
const lower = text.toLowerCase();
36+
const lower = normalizeLowercaseStringOrEmpty(text);
3337
return (
3438
lower.includes("worked") &&
3539
lower.includes("failed") &&
@@ -39,7 +43,7 @@ export function hasDiscoveryLabels(text: string) {
3943
}
4044

4145
export function reportsMissingDiscoveryFiles(text: string) {
42-
const lower = text.toLowerCase();
46+
const lower = normalizeLowercaseStringOrEmpty(text);
4347
if (confirmsDiscoveryFileRead(text)) {
4448
return false;
4549
}
@@ -52,6 +56,6 @@ export function reportsMissingDiscoveryFiles(text: string) {
5256
}
5357

5458
export function reportsDiscoveryScopeLeak(text: string) {
55-
const lower = text.toLowerCase();
59+
const lower = normalizeLowercaseStringOrEmpty(text);
5660
return DISCOVERY_SCOPE_LEAK_PHRASES.some((phrase) => lower.includes(phrase));
5761
}

extensions/qa-lab/src/model-switch-eval.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
2+
13
export function hasModelSwitchContinuityEvidence(text: string) {
2-
const lower = text.toLowerCase();
4+
const lower = normalizeLowercaseStringOrEmpty(text);
35
const mentionsHandoff =
46
lower.includes("handoff") || lower.includes("model switch") || lower.includes("switched");
57
const mentionsKickoffTask =

extensions/qa-lab/src/suite.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2372,7 +2372,7 @@ When the user asks for the hot install marker exactly, reply with exactly: HOT-I
23722372
(candidate) =>
23732373
candidate.direction === "outbound" &&
23742374
candidate.conversation.id === "qa-operator" &&
2375-
candidate.text.toLowerCase().includes("lighthouse"),
2375+
normalizeLowercaseStringOrEmpty(candidate.text).includes("lighthouse"),
23762376
)
23772377
.at(-1),
23782378
liveTurnTimeoutMs(env, 45_000),

src/cron/service/ops.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ export async function listPage(state: CronServiceState, opts?: CronListPageOptio
236236
if (!query) {
237237
return true;
238238
}
239-
const haystack = [job.name, job.description ?? "", job.agentId ?? ""].join(" ").toLowerCase();
239+
const haystack = normalizeLowercaseStringOrEmpty(
240+
[job.name, job.description ?? "", job.agentId ?? ""].join(" "),
241+
);
240242
return haystack.includes(query);
241243
});
242244
const sorted = sortJobs(filtered, sortBy, sortDir);

src/daemon/service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
12
import {
23
installLaunchAgent,
34
isLaunchAgentLoaded,
@@ -154,7 +155,7 @@ export function describeGatewayServiceRestart(
154155
return {
155156
scheduled: true,
156157
daemonActionResult: "scheduled",
157-
message: `restart scheduled, ${serviceNoun.toLowerCase()} will restart momentarily`,
158+
message: `restart scheduled, ${normalizeLowercaseStringOrEmpty(serviceNoun)} will restart momentarily`,
158159
progressMessage: `${serviceNoun} service restart scheduled.`,
159160
};
160161
}

0 commit comments

Comments
 (0)