mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-23 14:45:46 +00:00
refactor: dedupe routing lowercase helpers
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { CliBackendConfig } from "../config/types.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
import { isRecord } from "../utils.js";
|
||||
|
||||
type CliUsage = {
|
||||
@@ -23,7 +24,7 @@ export type CliStreamingDelta = {
|
||||
};
|
||||
|
||||
function isClaudeCliProvider(providerId: string): boolean {
|
||||
return providerId.trim().toLowerCase() === "claude-cli";
|
||||
return normalizeLowercaseStringOrEmpty(providerId) === "claude-cli";
|
||||
}
|
||||
|
||||
function extractJsonObjectCandidates(raw: string): string[] {
|
||||
|
||||
@@ -14,7 +14,11 @@ import { readClaudeCliCredentialsCached } from "../agents/cli-credentials.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveExecutablePath } from "../infra/executable-path.js";
|
||||
import { normalizeOptionalString, resolvePrimaryStringValue } from "../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
resolvePrimaryStringValue,
|
||||
} from "../shared/string-coerce.js";
|
||||
import { note } from "../terminal/note.js";
|
||||
import { shortenHomePath } from "../utils.js";
|
||||
|
||||
@@ -32,11 +36,11 @@ function usesClaudeCliModelSelection(cfg: OpenClawConfig): boolean {
|
||||
const primary = resolvePrimaryStringValue(
|
||||
cfg.agents?.defaults?.model as string | { primary?: string; fallbacks?: string[] } | undefined,
|
||||
);
|
||||
if (primary?.trim().toLowerCase().startsWith(`${CLAUDE_CLI_PROVIDER}/`)) {
|
||||
if (normalizeOptionalLowercaseString(primary)?.startsWith(`${CLAUDE_CLI_PROVIDER}/`)) {
|
||||
return true;
|
||||
}
|
||||
return Object.keys(cfg.agents?.defaults?.models ?? {}).some((key) =>
|
||||
key.trim().toLowerCase().startsWith(`${CLAUDE_CLI_PROVIDER}/`),
|
||||
normalizeOptionalLowercaseString(key)?.startsWith(`${CLAUDE_CLI_PROVIDER}/`),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,7 +49,11 @@ function hasClaudeCliConfigSignals(cfg: OpenClawConfig): boolean {
|
||||
return true;
|
||||
}
|
||||
const backendConfig = cfg.agents?.defaults?.cliBackends ?? {};
|
||||
if (Object.keys(backendConfig).some((key) => key.trim().toLowerCase() === CLAUDE_CLI_PROVIDER)) {
|
||||
if (
|
||||
Object.keys(backendConfig).some(
|
||||
(key) => normalizeOptionalLowercaseString(key) === CLAUDE_CLI_PROVIDER,
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return Object.values(cfg.auth?.profiles ?? {}).some(
|
||||
@@ -63,7 +71,7 @@ function hasClaudeCliStoreSignals(store: AuthProfileStore): boolean {
|
||||
function resolveClaudeCliCommand(cfg: OpenClawConfig): string {
|
||||
const configured = cfg.agents?.defaults?.cliBackends ?? {};
|
||||
for (const [key, entry] of Object.entries(configured)) {
|
||||
if (key.trim().toLowerCase() !== CLAUDE_CLI_PROVIDER) {
|
||||
if (normalizeOptionalLowercaseString(key) !== CLAUDE_CLI_PROVIDER) {
|
||||
continue;
|
||||
}
|
||||
const command = normalizeOptionalString(entry?.command);
|
||||
|
||||
@@ -5,6 +5,10 @@ import { normalizeProviderId } from "../agents/provider-id.js";
|
||||
import { resolveAgentModelPrimaryValue } from "../config/model-input.js";
|
||||
import type { SessionEntry } from "../config/sessions/types.js";
|
||||
import type { OpenClawConfig } from "../config/types.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalLowercaseString,
|
||||
} from "../shared/string-coerce.js";
|
||||
|
||||
function resolveStatusModelRefFromRaw(params: {
|
||||
cfg: OpenClawConfig;
|
||||
@@ -17,11 +21,11 @@ function resolveStatusModelRefFromRaw(params: {
|
||||
}
|
||||
const configuredModels = params.cfg.agents?.defaults?.models ?? {};
|
||||
if (!trimmed.includes("/")) {
|
||||
const aliasKey = trimmed.toLowerCase();
|
||||
const aliasKey = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
for (const [modelKey, entry] of Object.entries(configuredModels)) {
|
||||
const aliasValue = (entry as { alias?: unknown } | undefined)?.alias;
|
||||
const alias = typeof aliasValue === "string" ? aliasValue.trim() : "";
|
||||
if (!alias || alias.toLowerCase() !== aliasKey) {
|
||||
if (!alias || normalizeOptionalLowercaseString(alias) !== aliasKey) {
|
||||
continue;
|
||||
}
|
||||
const parsed = parseModelRef(modelKey, params.defaultProvider, {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
normalizeOptionalLowercaseString,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import {
|
||||
resolveMemorySlotDecisionShared,
|
||||
resolveEnableStateShared,
|
||||
@@ -69,12 +73,21 @@ function getBundledPluginAliasLookup(): ReadonlyMap<string, string> {
|
||||
if (plugin.origin !== "bundled") {
|
||||
continue;
|
||||
}
|
||||
lookup.set(plugin.id.toLowerCase(), plugin.id);
|
||||
const pluginId = normalizeOptionalLowercaseString(plugin.id);
|
||||
if (pluginId) {
|
||||
lookup.set(pluginId, plugin.id);
|
||||
}
|
||||
for (const providerId of plugin.providers) {
|
||||
lookup.set(providerId.toLowerCase(), plugin.id);
|
||||
const normalizedProviderId = normalizeOptionalLowercaseString(providerId);
|
||||
if (normalizedProviderId) {
|
||||
lookup.set(normalizedProviderId, plugin.id);
|
||||
}
|
||||
}
|
||||
for (const legacyPluginId of plugin.legacyPluginIds ?? []) {
|
||||
lookup.set(legacyPluginId.toLowerCase(), plugin.id);
|
||||
const normalizedLegacyPluginId = normalizeOptionalLowercaseString(legacyPluginId);
|
||||
if (normalizedLegacyPluginId) {
|
||||
lookup.set(normalizedLegacyPluginId, plugin.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
bundledPluginAliasLookupCache = lookup;
|
||||
@@ -82,8 +95,9 @@ function getBundledPluginAliasLookup(): ReadonlyMap<string, string> {
|
||||
}
|
||||
|
||||
export function normalizePluginId(id: string): string {
|
||||
const trimmed = id.trim();
|
||||
return getBundledPluginAliasLookup().get(trimmed.toLowerCase()) ?? trimmed;
|
||||
const trimmed = normalizeOptionalString(id) ?? "";
|
||||
const normalized = normalizeOptionalLowercaseString(trimmed) ?? "";
|
||||
return getBundledPluginAliasLookup().get(normalized) ?? trimmed;
|
||||
}
|
||||
|
||||
const PLUGIN_ACTIVATION_REASON_BY_CAUSE: Record<PluginActivationCause, string> = {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { isBlockedObjectKey } from "../infra/prototype-keys.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
export const DEFAULT_ACCOUNT_ID = "default";
|
||||
|
||||
@@ -12,11 +13,11 @@ const normalizeAccountIdCache = new Map<string, string>();
|
||||
const normalizeOptionalAccountIdCache = new Map<string, string | undefined>();
|
||||
|
||||
function canonicalizeAccountId(value: string): string {
|
||||
const normalized = normalizeLowercaseStringOrEmpty(value);
|
||||
if (VALID_ID_RE.test(value)) {
|
||||
return value.toLowerCase();
|
||||
return normalized;
|
||||
}
|
||||
return value
|
||||
.toLowerCase()
|
||||
return normalized
|
||||
.replace(INVALID_CHARS_RE, "-")
|
||||
.replace(LEADING_DASH_RE, "")
|
||||
.replace(TRAILING_DASH_RE, "")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
|
||||
export function resolveAccountEntry<T>(
|
||||
accounts: Record<string, T> | undefined,
|
||||
accountId: string,
|
||||
@@ -8,8 +10,10 @@ export function resolveAccountEntry<T>(
|
||||
if (Object.hasOwn(accounts, accountId)) {
|
||||
return accounts[accountId];
|
||||
}
|
||||
const normalized = accountId.toLowerCase();
|
||||
const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalized);
|
||||
const normalized = normalizeLowercaseStringOrEmpty(accountId);
|
||||
const matchKey = Object.keys(accounts).find(
|
||||
(key) => normalizeLowercaseStringOrEmpty(key) === normalized,
|
||||
);
|
||||
return matchKey ? accounts[matchKey] : undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,7 @@ export function scopedHeartbeatWakeOptions<T extends object>(
|
||||
}
|
||||
|
||||
export function normalizeMainKey(value: string | undefined | null): string {
|
||||
const trimmed = (value ?? "").trim();
|
||||
return trimmed ? trimmed.toLowerCase() : DEFAULT_MAIN_KEY;
|
||||
return normalizeLowercaseStringOrEmpty(value) || DEFAULT_MAIN_KEY;
|
||||
}
|
||||
|
||||
export function toAgentRequestSessionKey(storeKey: string | undefined | null): string | undefined {
|
||||
@@ -57,14 +56,14 @@ export function toAgentStoreSessionKey(params: {
|
||||
mainKey?: string | undefined;
|
||||
}): string {
|
||||
const raw = (params.requestKey ?? "").trim();
|
||||
if (!raw || raw.toLowerCase() === DEFAULT_MAIN_KEY) {
|
||||
const lowered = normalizeLowercaseStringOrEmpty(raw);
|
||||
if (!raw || lowered === DEFAULT_MAIN_KEY) {
|
||||
return buildAgentMainSessionKey({ agentId: params.agentId, mainKey: params.mainKey });
|
||||
}
|
||||
const parsed = parseAgentSessionKey(raw);
|
||||
if (parsed) {
|
||||
return `agent:${parsed.agentId}:${parsed.rest}`;
|
||||
}
|
||||
const lowered = raw.toLowerCase();
|
||||
if (lowered.startsWith("agent:")) {
|
||||
return lowered;
|
||||
}
|
||||
@@ -84,7 +83,9 @@ export function classifySessionKeyShape(sessionKey: string | undefined | null):
|
||||
if (parseAgentSessionKey(raw)) {
|
||||
return "agent";
|
||||
}
|
||||
return raw.toLowerCase().startsWith("agent:") ? "malformed_agent" : "legacy_or_alias";
|
||||
return normalizeLowercaseStringOrEmpty(raw).startsWith("agent:")
|
||||
? "malformed_agent"
|
||||
: "legacy_or_alias";
|
||||
}
|
||||
|
||||
export function normalizeAgentId(value: string | undefined | null): string {
|
||||
@@ -92,14 +93,14 @@ export function normalizeAgentId(value: string | undefined | null): string {
|
||||
if (!trimmed) {
|
||||
return DEFAULT_AGENT_ID;
|
||||
}
|
||||
const normalized = normalizeLowercaseStringOrEmpty(trimmed);
|
||||
// Keep it path-safe + shell-friendly.
|
||||
if (VALID_ID_RE.test(trimmed)) {
|
||||
return trimmed.toLowerCase();
|
||||
return normalized;
|
||||
}
|
||||
// Best-effort fallback: collapse invalid characters to "-"
|
||||
return (
|
||||
trimmed
|
||||
.toLowerCase()
|
||||
normalized
|
||||
.replace(INVALID_CHARS_RE, "-")
|
||||
.replace(LEADING_DASH_RE, "")
|
||||
.replace(TRAILING_DASH_RE, "")
|
||||
@@ -151,7 +152,7 @@ export function buildAgentPeerSessionKey(params: {
|
||||
if (linkedPeerId) {
|
||||
peerId = linkedPeerId;
|
||||
}
|
||||
peerId = peerId.toLowerCase();
|
||||
peerId = normalizeLowercaseStringOrEmpty(peerId);
|
||||
if (dmScope === "per-account-channel-peer" && peerId) {
|
||||
const channel = normalizeLowercaseStringOrEmpty(params.channel) || "unknown";
|
||||
const accountId = normalizeAccountId(params.accountId);
|
||||
@@ -170,7 +171,7 @@ export function buildAgentPeerSessionKey(params: {
|
||||
});
|
||||
}
|
||||
const channel = normalizeLowercaseStringOrEmpty(params.channel) || "unknown";
|
||||
const peerId = ((params.peerId ?? "").trim() || "unknown").toLowerCase();
|
||||
const peerId = normalizeLowercaseStringOrEmpty(params.peerId) || "unknown";
|
||||
return `agent:${normalizeAgentId(params.agentId)}:${channel}:${peerKind}:${peerId}`;
|
||||
}
|
||||
|
||||
@@ -228,7 +229,7 @@ export function buildGroupHistoryKey(params: {
|
||||
}): string {
|
||||
const channel = normalizeToken(params.channel) || "unknown";
|
||||
const accountId = normalizeAccountId(params.accountId);
|
||||
const peerId = params.peerId.trim().toLowerCase() || "unknown";
|
||||
const peerId = normalizeLowercaseStringOrEmpty(params.peerId) || "unknown";
|
||||
return `${channel}:${accountId}:${params.peerKind}:${peerId}`;
|
||||
}
|
||||
|
||||
@@ -243,12 +244,11 @@ export function resolveThreadSessionKeys(params: {
|
||||
if (!threadId) {
|
||||
return { sessionKey: params.baseSessionKey, parentSessionKey: undefined };
|
||||
}
|
||||
const normalizedThreadId = (params.normalizeThreadId ?? ((value: string) => value.toLowerCase()))(
|
||||
threadId,
|
||||
);
|
||||
const normalizedThread =
|
||||
params.normalizeThreadId?.(threadId) ?? normalizeLowercaseStringOrEmpty(threadId);
|
||||
const useSuffix = params.useSuffix ?? true;
|
||||
const sessionKey = useSuffix
|
||||
? `${params.baseSessionKey}:thread:${normalizedThreadId}`
|
||||
? `${params.baseSessionKey}:thread:${normalizedThread}`
|
||||
: params.baseSessionKey;
|
||||
return { sessionKey, parentSessionKey: params.parentSessionKey };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user