mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 23:50:20 +00:00
refactor: dedupe helper string normalization
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
|
||||
export function normalizeText(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { onAgentEvent } from "../infra/agent-events.js";
|
||||
import { requestHeartbeatNow } from "../infra/heartbeat-wake.js";
|
||||
import { enqueueSystemEvent } from "../infra/system-events.js";
|
||||
import { scopedHeartbeatWakeOptions } from "../routing/session-key.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { recordTaskRunProgressByRunId } from "../tasks/task-executor.js";
|
||||
|
||||
const DEFAULT_STREAM_FLUSH_MS = 2_500;
|
||||
@@ -30,11 +31,7 @@ function truncate(value: string, maxChars: number): string {
|
||||
}
|
||||
|
||||
function toTrimmedString(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
function toFiniteNumber(value: unknown): number | undefined {
|
||||
@@ -49,14 +46,14 @@ function resolveAcpStreamLogPathFromSessionFile(sessionFile: string, sessionId:
|
||||
export function resolveAcpSpawnStreamLogPath(params: {
|
||||
childSessionKey: string;
|
||||
}): string | undefined {
|
||||
const childSessionKey = params.childSessionKey.trim();
|
||||
const childSessionKey = normalizeOptionalString(params.childSessionKey);
|
||||
if (!childSessionKey) {
|
||||
return undefined;
|
||||
}
|
||||
const storeEntry = readAcpSessionEntry({
|
||||
sessionKey: childSessionKey,
|
||||
});
|
||||
const sessionId = storeEntry?.entry?.sessionId?.trim();
|
||||
const sessionId = normalizeOptionalString(storeEntry?.entry?.sessionId);
|
||||
if (!storeEntry || !sessionId) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -87,8 +84,8 @@ export function startAcpSpawnParentStreamRelay(params: {
|
||||
maxRelayLifetimeMs?: number;
|
||||
emitStartNotice?: boolean;
|
||||
}): AcpSpawnParentRelayHandle {
|
||||
const runId = params.runId.trim();
|
||||
const parentSessionKey = params.parentSessionKey.trim();
|
||||
const runId = normalizeOptionalString(params.runId) ?? "";
|
||||
const parentSessionKey = normalizeOptionalString(params.parentSessionKey) ?? "";
|
||||
if (!runId || !parentSessionKey) {
|
||||
return {
|
||||
dispose: () => {},
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
|
||||
export function normalizeSubagentSessionKey(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { SessionEntry } from "../config/sessions.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { formatProviderModelRef } from "./model-runtime.js";
|
||||
import type { RuntimeFallbackAttempt } from "./reply/agent-runner-execution.js";
|
||||
|
||||
@@ -10,8 +11,7 @@ export type FallbackNoticeState = Pick<
|
||||
>;
|
||||
|
||||
export function normalizeFallbackModelRef(value?: string): string | undefined {
|
||||
const trimmed = String(value ?? "").trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
function truncateFallbackReasonPart(value: string, max = FALLBACK_REASON_PART_MAX): string {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { listChannelCatalogEntries } from "../plugins/channel-catalog-registry.js";
|
||||
import type { PluginPackageChannel } from "../plugins/manifest.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { CHAT_CHANNEL_ORDER, type ChatChannelId } from "./ids.js";
|
||||
import { resolveChannelExposure } from "./plugins/exposure.js";
|
||||
import type { ChannelMeta } from "./plugins/types.js";
|
||||
@@ -12,7 +13,7 @@ function toChatChannelMeta(params: {
|
||||
id: ChatChannelId;
|
||||
channel: PluginPackageChannel;
|
||||
}): ChatChannelMeta {
|
||||
const label = params.channel.label?.trim();
|
||||
const label = normalizeOptionalString(params.channel.label);
|
||||
if (!label) {
|
||||
throw new Error(`Missing label for bundled chat channel "${params.id}"`);
|
||||
}
|
||||
@@ -21,10 +22,10 @@ function toChatChannelMeta(params: {
|
||||
return {
|
||||
id: params.id,
|
||||
label,
|
||||
selectionLabel: params.channel.selectionLabel?.trim() || label,
|
||||
docsPath: params.channel.docsPath?.trim() || `/channels/${params.id}`,
|
||||
docsLabel: params.channel.docsLabel?.trim() || undefined,
|
||||
blurb: params.channel.blurb?.trim() || "",
|
||||
selectionLabel: normalizeOptionalString(params.channel.selectionLabel) || label,
|
||||
docsPath: normalizeOptionalString(params.channel.docsPath) || `/channels/${params.id}`,
|
||||
docsLabel: normalizeOptionalString(params.channel.docsLabel),
|
||||
blurb: normalizeOptionalString(params.channel.blurb) || "",
|
||||
...(params.channel.aliases?.length ? { aliases: params.channel.aliases } : {}),
|
||||
...(params.channel.order !== undefined ? { order: params.channel.order } : {}),
|
||||
...(params.channel.selectionDocsPrefix !== undefined
|
||||
@@ -36,11 +37,11 @@ function toChatChannelMeta(params: {
|
||||
...(params.channel.selectionExtras?.length
|
||||
? { selectionExtras: params.channel.selectionExtras }
|
||||
: {}),
|
||||
...(params.channel.detailLabel?.trim()
|
||||
? { detailLabel: params.channel.detailLabel.trim() }
|
||||
...(normalizeOptionalString(params.channel.detailLabel)
|
||||
? { detailLabel: normalizeOptionalString(params.channel.detailLabel)! }
|
||||
: {}),
|
||||
...(params.channel.systemImage?.trim()
|
||||
? { systemImage: params.channel.systemImage.trim() }
|
||||
...(normalizeOptionalString(params.channel.systemImage)
|
||||
? { systemImage: normalizeOptionalString(params.channel.systemImage)! }
|
||||
: {}),
|
||||
...(params.channel.markdownCapable !== undefined
|
||||
? { markdownCapable: params.channel.markdownCapable }
|
||||
@@ -69,7 +70,7 @@ export function buildChatChannelMetaById(): Record<ChatChannelId, ChatChannelMet
|
||||
if (!channel) {
|
||||
continue;
|
||||
}
|
||||
const rawId = channel?.id?.trim();
|
||||
const rawId = normalizeOptionalString(channel.id);
|
||||
if (!rawId || !CHAT_CHANNEL_ID_SET.has(rawId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CronSchedule } from "../../cron/types.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { parseAt, parseCronStaggerMs, parseDurationMs } from "./shared.js";
|
||||
|
||||
type ScheduleOptionInput = {
|
||||
@@ -126,8 +127,7 @@ function resolveDirectSchedule(options: NormalizedScheduleOptions): CronSchedule
|
||||
}
|
||||
|
||||
function readOptionalString(value: unknown): string | undefined {
|
||||
const trimmed = readTrimmedString(value);
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
function readTrimmedString(value: unknown): string {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from "../agents/skills-clawhub.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { theme } from "../terminal/theme.js";
|
||||
import { formatSkillInfo, formatSkillsCheck, formatSkillsList } from "./skills-cli.format.js";
|
||||
@@ -67,7 +68,7 @@ export function registerSkillsCli(program: Command) {
|
||||
.action(async (queryParts: string[], opts: { limit?: number; json?: boolean }) => {
|
||||
try {
|
||||
const results = await searchSkillsFromClawHub({
|
||||
query: queryParts.join(" ").trim() || undefined,
|
||||
query: normalizeOptionalString(queryParts.join(" ")),
|
||||
limit: opts.limit,
|
||||
});
|
||||
if (opts.json) {
|
||||
|
||||
@@ -14,6 +14,7 @@ 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 } from "../shared/string-coerce.js";
|
||||
import { note } from "../terminal/note.js";
|
||||
import { shortenHomePath } from "../utils.js";
|
||||
|
||||
@@ -31,18 +32,12 @@ function resolveConfiguredPrimaryModelRef(
|
||||
value: string | { primary?: string; fallbacks?: string[] } | undefined,
|
||||
): string | undefined {
|
||||
if (typeof value === "string") {
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
||||
return undefined;
|
||||
}
|
||||
const primary = value.primary;
|
||||
if (typeof primary !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = primary.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value.primary);
|
||||
}
|
||||
|
||||
function usesClaudeCliModelSelection(cfg: OpenClawConfig): boolean {
|
||||
@@ -83,7 +78,7 @@ function resolveClaudeCliCommand(cfg: OpenClawConfig): string {
|
||||
if (key.trim().toLowerCase() !== CLAUDE_CLI_PROVIDER) {
|
||||
continue;
|
||||
}
|
||||
const command = entry?.command?.trim();
|
||||
const command = normalizeOptionalString(entry?.command);
|
||||
if (command) {
|
||||
return command;
|
||||
}
|
||||
@@ -120,7 +115,7 @@ export function resolveClaudeCliProjectDirForWorkspace(params: {
|
||||
workspaceDir: string;
|
||||
homeDir?: string;
|
||||
}): string {
|
||||
const homeDir = params.homeDir?.trim() || process.env.HOME || os.homedir();
|
||||
const homeDir = normalizeOptionalString(params.homeDir) || process.env.HOME || os.homedir();
|
||||
const canonicalWorkspaceDir = canonicalizeWorkspaceDir(params.workspaceDir);
|
||||
return path.join(
|
||||
homeDir,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import type { AgentModelConfig } from "./types.agents-shared.js";
|
||||
|
||||
type AgentModelListLike = {
|
||||
@@ -7,14 +8,12 @@ type AgentModelListLike = {
|
||||
|
||||
export function resolveAgentModelPrimaryValue(model?: AgentModelConfig): string | undefined {
|
||||
if (typeof model === "string") {
|
||||
const trimmed = model.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(model);
|
||||
}
|
||||
if (!model || typeof model !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
const primary = model.primary?.trim();
|
||||
return primary || undefined;
|
||||
return normalizeOptionalString(model.primary);
|
||||
}
|
||||
|
||||
export function resolveAgentModelFallbackValues(model?: AgentModelConfig): string[] {
|
||||
@@ -26,7 +25,7 @@ export function resolveAgentModelFallbackValues(model?: AgentModelConfig): strin
|
||||
|
||||
export function toAgentModelListLike(model?: AgentModelConfig): AgentModelListLike | undefined {
|
||||
if (typeof model === "string") {
|
||||
const primary = model.trim();
|
||||
const primary = normalizeOptionalString(model);
|
||||
return primary ? { primary } : undefined;
|
||||
}
|
||||
if (!model || typeof model !== "object") {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { IncomingMessage, ServerResponse } from "node:http";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { resolveMainSessionKey } from "../config/sessions.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { normalizeMessageChannel } from "../utils/message-channel.js";
|
||||
import { getHeader } from "./http-utils.js";
|
||||
|
||||
@@ -16,7 +17,7 @@ function resolveScopedSessionKey(
|
||||
cfg: ReturnType<typeof loadConfig>,
|
||||
rawSessionKey: string | undefined,
|
||||
): string {
|
||||
const trimmed = rawSessionKey?.trim();
|
||||
const trimmed = normalizeOptionalString(rawSessionKey);
|
||||
return !trimmed || trimmed === "main" ? resolveMainSessionKey(cfg) : trimmed;
|
||||
}
|
||||
|
||||
@@ -95,6 +96,6 @@ export function resolveMcpRequestContext(
|
||||
sessionKey: resolveScopedSessionKey(cfg, getHeader(req, "x-session-key")),
|
||||
messageProvider:
|
||||
normalizeMessageChannel(getHeader(req, "x-openclaw-message-channel")) ?? undefined,
|
||||
accountId: getHeader(req, "x-openclaw-account-id")?.trim() || undefined,
|
||||
accountId: normalizeOptionalString(getHeader(req, "x-openclaw-account-id")),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
|
||||
export function parseRestartRequestParams(params: unknown): {
|
||||
sessionKey: string | undefined;
|
||||
note: string | undefined;
|
||||
restartDelayMs: number | undefined;
|
||||
} {
|
||||
const sessionKey =
|
||||
typeof (params as { sessionKey?: unknown }).sessionKey === "string"
|
||||
? (params as { sessionKey?: string }).sessionKey?.trim() || undefined
|
||||
: undefined;
|
||||
const note =
|
||||
typeof (params as { note?: unknown }).note === "string"
|
||||
? (params as { note?: string }).note?.trim() || undefined
|
||||
: undefined;
|
||||
const sessionKey = normalizeOptionalString((params as { sessionKey?: unknown }).sessionKey);
|
||||
const note = normalizeOptionalString((params as { note?: unknown }).note);
|
||||
const restartDelayMsRaw = (params as { restartDelayMs?: unknown }).restartDelayMs;
|
||||
const restartDelayMs =
|
||||
typeof restartDelayMsRaw === "number" && Number.isFinite(restartDelayMsRaw)
|
||||
|
||||
@@ -8,6 +8,7 @@ import { loadConfig } from "../config/config.js";
|
||||
import { resolveMainSessionKey } from "../config/sessions.js";
|
||||
import { logWarn } from "../logger.js";
|
||||
import { isTestDefaultMemorySlotDisabled } from "../plugins/config-state.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { normalizeMessageChannel } from "../utils/message-channel.js";
|
||||
import type { AuthRateLimiter } from "./auth-rate-limit.js";
|
||||
import type { ResolvedGatewayAuth } from "./auth.js";
|
||||
@@ -225,9 +226,9 @@ export async function handleToolsInvokeHttpRequest(
|
||||
const messageChannel = normalizeMessageChannel(
|
||||
getHeader(req, "x-openclaw-message-channel") ?? "",
|
||||
);
|
||||
const accountId = getHeader(req, "x-openclaw-account-id")?.trim() || undefined;
|
||||
const agentTo = getHeader(req, "x-openclaw-message-to")?.trim() || undefined;
|
||||
const agentThreadId = getHeader(req, "x-openclaw-thread-id")?.trim() || undefined;
|
||||
const accountId = normalizeOptionalString(getHeader(req, "x-openclaw-account-id"));
|
||||
const agentTo = normalizeOptionalString(getHeader(req, "x-openclaw-message-to"));
|
||||
const agentThreadId = normalizeOptionalString(getHeader(req, "x-openclaw-thread-id"));
|
||||
const { agentId, tools } = resolveGatewayScopedTools({
|
||||
cfg,
|
||||
sessionKey,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
|
||||
export type InteractiveButtonStyle = "primary" | "secondary" | "success" | "danger";
|
||||
|
||||
export type InteractiveReplyButton = {
|
||||
@@ -37,11 +39,7 @@ export type InteractiveReply = {
|
||||
};
|
||||
|
||||
function readTrimmedString(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
function normalizeButtonStyle(value: unknown): InteractiveButtonStyle | undefined {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { homedir, platform } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import { normalizeOptionalSecretInput } from "../utils/normalize-secret-input.js";
|
||||
|
||||
const GCLOUD_DEFAULT_ADC_PATH = join(
|
||||
@@ -16,11 +17,7 @@ function hasAnthropicVertexMetadataServerAdc(env: NodeJS.ProcessEnv = process.en
|
||||
}
|
||||
|
||||
function normalizeOptionalPathInput(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
function resolveAnthropicVertexDefaultAdcPath(env: NodeJS.ProcessEnv = process.env): string {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import type { OpenClawConfig } from "./config-runtime.js";
|
||||
|
||||
type ApprovalKind = "exec" | "plugin";
|
||||
|
||||
function defaultNormalizeSenderId(value: string): string | undefined {
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
export function createResolvedApproverActionAuthAdapter(params: {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { matchesApprovalRequestFilters } from "../infra/approval-request-filters
|
||||
import { getExecApprovalReplyMetadata } from "../infra/exec-approval-reply.js";
|
||||
import type { ExecApprovalRequest } from "../infra/exec-approvals.js";
|
||||
import type { PluginApprovalRequest } from "../infra/plugin-approvals.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import type { OpenClawConfig } from "./config-runtime.js";
|
||||
import { normalizeAccountId } from "./routing.js";
|
||||
|
||||
@@ -24,8 +25,7 @@ type ApprovalProfileParams = {
|
||||
};
|
||||
|
||||
function defaultNormalizeSenderId(value: string): string | undefined {
|
||||
const trimmed = value.trim();
|
||||
return trimmed || undefined;
|
||||
return normalizeOptionalString(value);
|
||||
}
|
||||
|
||||
function isApprovalTargetsMode(cfg: OpenClawConfig): boolean {
|
||||
|
||||
Reference in New Issue
Block a user