mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-20 21:23:23 +00:00
refactor: dedupe extension lowercase helpers
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { createFeishuClient } from "./client.js";
|
||||
import type { ResolvedFeishuAccount } from "./types.js";
|
||||
|
||||
@@ -37,7 +38,7 @@ function correctFeishuScopeInUrl(url: string): string {
|
||||
}
|
||||
|
||||
function shouldSuppressPermissionErrorNotice(permissionError: FeishuPermissionError): boolean {
|
||||
const message = permissionError.message.toLowerCase();
|
||||
const message = normalizeLowercaseStringOrEmpty(permissionError.message);
|
||||
return IGNORED_PERMISSION_SCOPE_TOKENS.some((token) => message.includes(token));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { RuntimeEnv } from "../runtime-api.js";
|
||||
import { probeFeishu } from "./probe.js";
|
||||
import type { ResolvedFeishuAccount } from "./types.js";
|
||||
@@ -33,13 +34,12 @@ export type FeishuMonitorBotIdentity = {
|
||||
};
|
||||
|
||||
function isTimeoutErrorMessage(message: string | undefined): boolean {
|
||||
return !!(
|
||||
message?.toLowerCase().includes("timeout") || message?.toLowerCase().includes("timed out")
|
||||
);
|
||||
const lower = normalizeLowercaseStringOrEmpty(message);
|
||||
return lower.includes("timeout") || lower.includes("timed out");
|
||||
}
|
||||
|
||||
function isAbortErrorMessage(message: string | undefined): boolean {
|
||||
return message?.toLowerCase().includes("aborted") ?? false;
|
||||
return normalizeLowercaseStringOrEmpty(message).includes("aborted");
|
||||
}
|
||||
|
||||
export async function fetchBotIdentityForMonitor(
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
type OpenClawConfig,
|
||||
type SecretInput,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
inspectFeishuCredentials,
|
||||
resolveDefaultFeishuAccountId,
|
||||
@@ -102,7 +103,7 @@ function isFeishuConfigured(cfg: OpenClawConfig, accountId?: string | null): boo
|
||||
return false;
|
||||
}
|
||||
const rec = value as Record<string, unknown>;
|
||||
const source = normalizeString(rec.source)?.toLowerCase();
|
||||
const source = normalizeOptionalLowercaseString(normalizeString(rec.source));
|
||||
const id = normalizeString(rec.id);
|
||||
if (source === "env" && id) {
|
||||
return Boolean(normalizeString(process.env[id]));
|
||||
|
||||
@@ -47,7 +47,7 @@ export function normalizeIMessageHandle(raw: string): string {
|
||||
return "";
|
||||
}
|
||||
const value = trimmed.slice(prefix.length).trim();
|
||||
return `${prefix.toLowerCase()}${value}`;
|
||||
return `${normalizeLowercaseStringOrEmpty(prefix)}${value}`;
|
||||
}
|
||||
if (trimmed.includes("@")) {
|
||||
return normalizeLowercaseStringOrEmpty(trimmed);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { runCommandWithTimeout } from "openclaw/plugin-sdk/process-runtime";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { detectBinary } from "openclaw/plugin-sdk/setup";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { createIMessageRpcClient } from "./client.js";
|
||||
import { DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./constants.js";
|
||||
|
||||
@@ -35,7 +36,7 @@ async function probeRpcSupport(cliPath: string, timeoutMs: number): Promise<RpcS
|
||||
try {
|
||||
const result = await runCommandWithTimeout([cliPath, "rpc", "--help"], { timeoutMs });
|
||||
const combined = `${result.stdout}\n${result.stderr}`.trim();
|
||||
const normalized = combined.toLowerCase();
|
||||
const normalized = normalizeLowercaseStringOrEmpty(combined);
|
||||
if (normalized.includes("unknown command") && normalized.includes("rpc")) {
|
||||
const fatal = {
|
||||
supported: false,
|
||||
|
||||
@@ -21,7 +21,7 @@ function normalizeIMessageTestHandle(raw: string): string {
|
||||
}
|
||||
if (/^(chat_id:|chat_guid:|chat_identifier:)/i.test(trimmed)) {
|
||||
return trimmed.replace(/^(chat_id:|chat_guid:|chat_identifier:)/i, (match) =>
|
||||
match.toLowerCase(),
|
||||
normalizeLowercaseStringOrEmpty(match),
|
||||
);
|
||||
}
|
||||
if (trimmed.includes("@")) {
|
||||
|
||||
@@ -2,16 +2,16 @@ import {
|
||||
createResolvedApproverActionAuthAdapter,
|
||||
resolveApprovalApprovers,
|
||||
} from "openclaw/plugin-sdk/approval-auth-runtime";
|
||||
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveNextcloudTalkAccount } from "./accounts.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
function normalizeNextcloudTalkApproverId(value: string | number): string | undefined {
|
||||
const normalized = String(value)
|
||||
.trim()
|
||||
.replace(/^(nextcloud-talk|nc-talk|nc):/i, "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
return normalized || undefined;
|
||||
return normalizeOptionalLowercaseString(
|
||||
String(value)
|
||||
.trim()
|
||||
.replace(/^(nextcloud-talk|nc-talk|nc):/i, ""),
|
||||
);
|
||||
}
|
||||
|
||||
export const nextcloudTalkApprovalAuth = createResolvedApproverActionAuthAdapter({
|
||||
|
||||
@@ -39,11 +39,7 @@ export const nextcloudTalkSecurityAdapter = {
|
||||
resolveAllowFrom: (account) => account.config.allowFrom,
|
||||
policyPathSuffix: "dmPolicy",
|
||||
normalizeEntry: (raw) =>
|
||||
raw
|
||||
.trim()
|
||||
.replace(/^(nextcloud-talk|nc-talk|nc):/i, "")
|
||||
.trim()
|
||||
.toLowerCase(),
|
||||
normalizeLowercaseStringOrEmpty(raw.trim().replace(/^(nextcloud-talk|nc-talk|nc):/i, "")),
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type {
|
||||
AllowlistMatch,
|
||||
ChannelGroupContext,
|
||||
@@ -15,10 +16,7 @@ import {
|
||||
import type { NextcloudTalkRoomConfig } from "./types.js";
|
||||
|
||||
function normalizeAllowEntry(raw: string): string {
|
||||
return raw
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/^(nextcloud-talk|nc-talk|nc):/i, "");
|
||||
return normalizeLowercaseStringOrEmpty(raw.trim().replace(/^(nextcloud-talk|nc-talk|nc):/i, ""));
|
||||
}
|
||||
|
||||
export function normalizeNextcloudTalkAllowlist(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createHmac, randomBytes } from "node:crypto";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { NextcloudTalkWebhookHeaders } from "./types.js";
|
||||
|
||||
const SIGNATURE_HEADER = "x-nextcloud-talk-signature";
|
||||
@@ -41,7 +42,7 @@ export function extractNextcloudTalkHeaders(
|
||||
headers: Record<string, string | string[] | undefined>,
|
||||
): NextcloudTalkWebhookHeaders | null {
|
||||
const getHeader = (name: string): string | undefined => {
|
||||
const value = headers[name] ?? headers[name.toLowerCase()];
|
||||
const value = headers[name] ?? headers[normalizeLowercaseStringOrEmpty(name)];
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { fetchCodexUsage } from "openclaw/plugin-sdk/provider-usage";
|
||||
import { readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty, readStringValue } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { OPENAI_CODEX_DEFAULT_MODEL } from "./default-models.js";
|
||||
import { resolveCodexAuthIdentity } from "./openai-codex-auth-identity.js";
|
||||
import { buildOpenAICodexProvider } from "./openai-codex-catalog.js";
|
||||
@@ -110,7 +110,7 @@ function resolveCodexForwardCompatModel(
|
||||
ctx: ProviderResolveDynamicModelContext,
|
||||
): ProviderRuntimeModel | undefined {
|
||||
const trimmedModelId = ctx.modelId.trim();
|
||||
const lower = trimmedModelId.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(trimmedModelId);
|
||||
|
||||
let templateIds: readonly string[];
|
||||
let patch: Partial<ProviderRuntimeModel> | undefined;
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type ProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { applyOpenAIConfig, OPENAI_DEFAULT_MODEL } from "./default-models.js";
|
||||
import { buildOpenAIReplayPolicy } from "./replay-policy.js";
|
||||
import {
|
||||
@@ -106,7 +107,7 @@ function resolveOpenAIGpt54ForwardCompatModel(
|
||||
ctx: ProviderResolveDynamicModelContext,
|
||||
): ProviderRuntimeModel | undefined {
|
||||
const trimmedModelId = ctx.modelId.trim();
|
||||
const lower = trimmedModelId.toLowerCase();
|
||||
const lower = normalizeLowercaseStringOrEmpty(trimmedModelId);
|
||||
let templateIds: readonly string[];
|
||||
let patch: Partial<ProviderRuntimeModel>;
|
||||
if (lower === OPENAI_GPT_54_MODEL_ID) {
|
||||
@@ -252,7 +253,7 @@ export function buildOpenAIProvider(): ProviderPlugin {
|
||||
suppressBuiltInModel: (ctx) => {
|
||||
if (
|
||||
!SUPPRESSED_SPARK_PROVIDERS.has(normalizeProviderId(ctx.provider)) ||
|
||||
ctx.modelId.toLowerCase() !== OPENAI_DIRECT_SPARK_MODEL_ID
|
||||
normalizeLowercaseStringOrEmpty(ctx.modelId) !== OPENAI_DIRECT_SPARK_MODEL_ID
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
ProviderWebSocketSessionPolicy,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { isOpenAIApiBaseUrl, isOpenAICodexBaseUrl } from "./shared.js";
|
||||
|
||||
const DEFAULT_OPENAI_WS_DEGRADE_COOLDOWN_MS = 60_000;
|
||||
@@ -17,7 +18,7 @@ function isAzureOpenAIBaseUrl(baseUrl?: string): boolean {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return new URL(trimmed).hostname.toLowerCase().endsWith(".openai.azure.com");
|
||||
return normalizeLowercaseStringOrEmpty(new URL(trimmed).hostname).endsWith(".openai.azure.com");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ function extractSlackSessionKind(
|
||||
return null;
|
||||
}
|
||||
const match = sessionKey.match(/slack:(direct|channel|group):/i);
|
||||
return match?.[1] ? (match[1].toLowerCase() as "direct" | "channel" | "group") : null;
|
||||
const kind = normalizeLowercaseStringOrEmpty(match?.[1]);
|
||||
return kind ? (kind as "direct" | "channel" | "group") : null;
|
||||
}
|
||||
|
||||
function normalizeComparableTarget(value: string): string {
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
type ChannelMatchSource,
|
||||
} from "openclaw/plugin-sdk/channel-targets";
|
||||
import type { SlackReactionNotificationMode } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { SlackMessageEvent } from "../types.js";
|
||||
import { allowListMatches, normalizeAllowListLower, normalizeSlackSlug } from "./allow-list.js";
|
||||
|
||||
@@ -108,7 +109,7 @@ export function resolveSlackChannelConfig(params: {
|
||||
// operators commonly write them in lowercase in their config. Add both
|
||||
// case variants so the lookup is case-insensitive without requiring a full
|
||||
// entry-scan. buildChannelKeyCandidates deduplicates identical keys.
|
||||
const channelIdLower = channelId.toLowerCase();
|
||||
const channelIdLower = normalizeLowercaseStringOrEmpty(channelId);
|
||||
const channelIdUpper = channelId.toUpperCase();
|
||||
const candidates = buildChannelKeyCandidates(
|
||||
channelId,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
||||
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { getChildLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
|
||||
import type { SlackMessageEvent } from "../types.js";
|
||||
import { normalizeAllowList, normalizeAllowListLower, normalizeSlackSlug } from "./allow-list.js";
|
||||
import type { SlackChannelConfigEntries } from "./channel-config.js";
|
||||
@@ -314,7 +315,7 @@ export function createSlackMonitorContext(params: {
|
||||
p.channelName ? normalizeSlackSlug(p.channelName) : undefined,
|
||||
]
|
||||
.filter((value): value is string => Boolean(value))
|
||||
.map((value) => value.toLowerCase());
|
||||
.map((value) => normalizeLowercaseStringOrEmpty(value));
|
||||
const permitted =
|
||||
groupDmChannelsLower.includes("*") ||
|
||||
candidates.some((candidate) => groupDmChannelsLower.includes(candidate));
|
||||
|
||||
@@ -25,7 +25,10 @@ import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
|
||||
import { resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
|
||||
import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveSlackReplyToMode, type ResolvedSlackAccount } from "../../accounts.js";
|
||||
import { reactSlackMessage } from "../../actions.js";
|
||||
import { hasSlackThreadParticipation } from "../../sent-thread-cache.js";
|
||||
@@ -788,7 +791,7 @@ export async function prepareSlackMessage(params: {
|
||||
pinnedMainDmOwner && message.user
|
||||
? {
|
||||
ownerRecipient: pinnedMainDmOwner,
|
||||
senderRecipient: message.user.toLowerCase(),
|
||||
senderRecipient: normalizeLowercaseStringOrEmpty(message.user),
|
||||
onSkip: ({ ownerRecipient, senderRecipient }) => {
|
||||
logVerbose(
|
||||
`slack: skip main-session last route for ${senderRecipient} (pinned owner ${ownerRecipient})`,
|
||||
|
||||
Reference in New Issue
Block a user