refactor: dedupe agent lowercase helpers

This commit is contained in:
Peter Steinberger
2026-04-07 11:40:14 +01:00
parent 3a2e347dc7
commit 37a7baf270
7 changed files with 31 additions and 24 deletions

View File

@@ -1,4 +1,5 @@
import { resolveProviderModernModelRef } from "../plugins/provider-runtime.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { normalizeProviderId } from "./provider-id.js";
export type ModelRef = {
@@ -53,7 +54,7 @@ function isHighSignalClaudeModelId(id: string): boolean {
export function isModernModelRef(ref: ModelRef): boolean {
const provider = normalizeProviderId(ref.provider ?? "");
const id = ref.id?.trim().toLowerCase() ?? "";
const id = normalizeLowercaseStringOrEmpty(ref.id);
if (!provider || !id) {
return false;
}
@@ -72,7 +73,7 @@ export function isModernModelRef(ref: ModelRef): boolean {
}
export function isHighSignalLiveModelRef(ref: ModelRef): boolean {
const id = ref.id?.trim().toLowerCase() ?? "";
const id = normalizeLowercaseStringOrEmpty(ref.id);
if (!isModernModelRef(ref) || !id) {
return false;
}
@@ -81,7 +82,7 @@ export function isHighSignalLiveModelRef(ref: ModelRef): boolean {
function toCanonicalHighSignalLiveModelKey(ref: ModelRef): string | null {
const provider = normalizeProviderId(ref.provider ?? "");
const rawId = ref.id?.trim().toLowerCase() ?? "";
const rawId = normalizeLowercaseStringOrEmpty(ref.id);
if (!provider || !rawId) {
return null;
}

View File

@@ -1,9 +1,10 @@
import { resolveProviderBuiltInModelSuppression } from "../plugins/provider-runtime.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { normalizeProviderId } from "./provider-id.js";
function resolveBuiltInModelSuppression(params: { provider?: string | null; id?: string | null }) {
const provider = normalizeProviderId(params.provider?.trim().toLowerCase() ?? "");
const modelId = params.id?.trim().toLowerCase() ?? "";
const provider = normalizeProviderId(params.provider ?? "");
const modelId = normalizeLowercaseStringOrEmpty(params.id);
if (!provider || !modelId) {
return undefined;
}

View File

@@ -1,6 +1,7 @@
import type { OpenClawConfig } from "../config/config.js";
import { callGateway } from "../gateway/call.js";
import { getActiveRuntimeWebToolsMetadata } from "../secrets/runtime.js";
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import { normalizeDeliveryContext } from "../utils/delivery-context.js";
import type { GatewayMessageChannel } from "../utils/message-channel.js";
import { resolveAgentWorkspaceDir, resolveSessionAgentId } from "./agent-scope.js";
@@ -44,7 +45,7 @@ const defaultOpenClawToolsDeps: OpenClawToolsDeps = {
let openClawToolsDeps: OpenClawToolsDeps = defaultOpenClawToolsDeps;
function isOpenAIProvider(provider?: string): boolean {
const normalized = provider?.trim().toLowerCase();
const normalized = normalizeOptionalLowercaseString(provider);
return normalized === "openai" || normalized === "openai-codex";
}

View File

@@ -6,6 +6,10 @@ import { resolveMergedSafeBinProfileFixtures } from "../infra/exec-safe-bin-runt
import { logWarn } from "../logger.js";
import { getPluginToolMeta } from "../plugins/tools.js";
import { isSubagentSessionKey } from "../routing/session-key.js";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalLowercaseString,
} from "../shared/string-coerce.js";
import { resolveGatewayMessageChannel } from "../utils/message-channel.js";
import { resolveAgentConfig } from "./agent-scope.js";
import { createApplyPatchTool } from "./apply-patch.js";
@@ -61,7 +65,7 @@ import {
import { resolveWorkspaceRoot } from "./workspace-dir.js";
function isOpenAIProvider(provider?: string) {
const normalized = provider?.trim().toLowerCase();
const normalized = normalizeOptionalLowercaseString(provider);
return normalized === "openai" || normalized === "openai-codex";
}
@@ -74,8 +78,7 @@ const TOOL_ALLOW_BY_MESSAGE_PROVIDER: Readonly<Record<string, readonly string[]>
const MEMORY_FLUSH_ALLOWED_TOOL_NAMES = new Set(["read", "write"]);
function normalizeMessageProvider(messageProvider?: string): string | undefined {
const normalized = messageProvider?.trim().toLowerCase();
return normalized && normalized.length > 0 ? normalized : undefined;
return normalizeOptionalLowercaseString(messageProvider);
}
function applyMessageProviderToolPolicy(
@@ -159,14 +162,14 @@ function isApplyPatchAllowedForModel(params: {
if (!modelId) {
return false;
}
const normalizedModelId = modelId.toLowerCase();
const provider = params.modelProvider?.trim().toLowerCase();
const normalizedModelId = normalizeLowercaseStringOrEmpty(modelId);
const provider = normalizeOptionalLowercaseString(params.modelProvider);
const normalizedFull =
provider && !normalizedModelId.includes("/")
? `${provider}/${normalizedModelId}`
: normalizedModelId;
return allowModels.some((entry) => {
const normalized = entry.trim().toLowerCase();
const normalized = normalizeOptionalLowercaseString(entry);
if (!normalized) {
return false;
}

View File

@@ -1,5 +1,7 @@
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
export function normalizeProviderId(provider: string): string {
const normalized = provider.trim().toLowerCase();
const normalized = normalizeLowercaseStringOrEmpty(provider);
if (normalized === "modelstudio" || normalized === "qwencloud") {
return "qwen";
}

View File

@@ -1,3 +1,7 @@
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalLowercaseString,
} from "../shared/string-coerce.js";
import { asRecord } from "./tool-display-record.js";
const MUTATING_TOOL_NAMES = new Set([
@@ -59,13 +63,7 @@ export type ToolActionRef = {
};
function normalizeActionName(value: unknown): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const normalized = value
.trim()
.toLowerCase()
.replace(/[\s-]+/g, "_");
const normalized = normalizeOptionalLowercaseString(value)?.replace(/[\s-]+/g, "_");
return normalized || undefined;
}
@@ -98,7 +96,7 @@ function appendFingerprintAlias(
}
export function isLikelyMutatingToolName(toolName: string): boolean {
const normalized = toolName.trim().toLowerCase();
const normalized = normalizeLowercaseStringOrEmpty(toolName);
if (!normalized) {
return false;
}
@@ -111,7 +109,7 @@ export function isLikelyMutatingToolName(toolName: string): boolean {
}
export function isMutatingToolCall(toolName: string, args: unknown): boolean {
const normalized = toolName.trim().toLowerCase();
const normalized = normalizeLowercaseStringOrEmpty(toolName);
const record = asRecord(args);
const action = normalizeActionName(record?.action);
@@ -159,7 +157,7 @@ export function buildToolActionFingerprint(
if (!isMutatingToolCall(toolName, args)) {
return undefined;
}
const normalizedTool = toolName.trim().toLowerCase();
const normalizedTool = normalizeLowercaseStringOrEmpty(toolName);
const record = asRecord(args);
const action = normalizeActionName(record?.action);
const parts = [`tool=${normalizedTool}`];

View File

@@ -1,3 +1,4 @@
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import {
expandToolGroups,
normalizeToolList,
@@ -112,7 +113,7 @@ export function buildPluginToolGroups<T extends { name: string }>(params: {
}
const name = normalizeToolName(tool.name);
all.push(name);
const pluginId = meta.pluginId.trim().toLowerCase();
const pluginId = normalizeOptionalLowercaseString(meta.pluginId);
if (!pluginId) {
continue;
}