mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-03 21:20:23 +00:00
refactor: dedupe gateway trimmed readers
This commit is contained in:
@@ -432,7 +432,7 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
}
|
||||
|
||||
const agentIdRaw = typeof request.agentId === "string" ? request.agentId.trim() : "";
|
||||
const agentIdRaw = normalizeOptionalString(request.agentId) ?? "";
|
||||
const agentId = agentIdRaw ? normalizeAgentId(agentIdRaw) : undefined;
|
||||
if (agentId) {
|
||||
const knownAgents = listAgentIds(cfg);
|
||||
@@ -449,10 +449,7 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
}
|
||||
|
||||
const requestedSessionKeyRaw =
|
||||
typeof request.sessionKey === "string" && request.sessionKey.trim()
|
||||
? request.sessionKey.trim()
|
||||
: undefined;
|
||||
const requestedSessionKeyRaw = normalizeOptionalString(request.sessionKey);
|
||||
if (
|
||||
requestedSessionKeyRaw &&
|
||||
classifySessionKeyShape(requestedSessionKeyRaw) === "malformed_agent"
|
||||
@@ -517,7 +514,7 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
requestedSessionKey = resetResult.key;
|
||||
resolvedSessionId = resetResult.sessionId ?? resolvedSessionId;
|
||||
const postResetMessage = resetCommandMatch[2]?.trim() ?? "";
|
||||
const postResetMessage = normalizeOptionalString(resetCommandMatch[2]) ?? "";
|
||||
if (postResetMessage) {
|
||||
message = postResetMessage;
|
||||
} else {
|
||||
@@ -867,8 +864,8 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const p = params;
|
||||
const agentIdRaw = typeof p.agentId === "string" ? p.agentId.trim() : "";
|
||||
const sessionKeyRaw = typeof p.sessionKey === "string" ? p.sessionKey.trim() : "";
|
||||
const agentIdRaw = normalizeOptionalString(p.agentId) ?? "";
|
||||
const sessionKeyRaw = normalizeOptionalString(p.sessionKey) ?? "";
|
||||
let agentId = agentIdRaw ? normalizeAgentId(agentIdRaw) : undefined;
|
||||
if (sessionKeyRaw) {
|
||||
if (classifySessionKeyShape(sessionKeyRaw) === "malformed_agent") {
|
||||
|
||||
@@ -553,7 +553,7 @@ export const agentsHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
|
||||
const cfg = loadConfig();
|
||||
const rawName = String(params.name ?? "").trim();
|
||||
const rawName = normalizeOptionalString(String(params.name ?? "")) ?? "";
|
||||
const agentId = normalizeAgentId(rawName);
|
||||
if (agentId === DEFAULT_AGENT_ID) {
|
||||
respond(
|
||||
@@ -573,7 +573,9 @@ export const agentsHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaceDir = resolveUserPath(String(params.workspace ?? "").trim());
|
||||
const workspaceDir = resolveUserPath(
|
||||
normalizeOptionalString(String(params.workspace ?? "")) ?? "",
|
||||
);
|
||||
|
||||
// Resolve agentDir against the config we're about to persist (vs the pre-write config),
|
||||
// so subsequent resolutions can't disagree about the agent's directory.
|
||||
|
||||
@@ -14,6 +14,7 @@ import { applyPluginAutoEnable } from "../../config/plugin-auto-enable.js";
|
||||
import { getChannelActivity } from "../../infra/channel-activity.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
errorShape,
|
||||
@@ -39,7 +40,7 @@ export async function logoutChannelAccount(params: {
|
||||
plugin: ChannelPlugin;
|
||||
}): Promise<ChannelLogoutPayload> {
|
||||
const resolvedAccountId =
|
||||
params.accountId?.trim() ||
|
||||
normalizeOptionalString(params.accountId) ||
|
||||
params.plugin.config.defaultAccountId?.(params.cfg) ||
|
||||
params.plugin.config.listAccountIds(params.cfg)[0] ||
|
||||
DEFAULT_ACCOUNT_ID;
|
||||
@@ -270,7 +271,7 @@ export const channelsHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const accountIdRaw = (params as { accountId?: unknown }).accountId;
|
||||
const accountId = typeof accountIdRaw === "string" ? accountIdRaw.trim() : undefined;
|
||||
const accountId = normalizeOptionalString(accountIdRaw);
|
||||
const snapshot = await readConfigFileSnapshot();
|
||||
if (!snapshot.valid) {
|
||||
respond(
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
buildSystemRunApprovalEnvBinding,
|
||||
} from "../../infra/system-run-approval-binding.js";
|
||||
import { resolveSystemRunApprovalRequestContext } from "../../infra/system-run-approval-context.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import type { ExecApprovalManager } from "../exec-approval-manager.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
@@ -143,9 +144,9 @@ export function createExecApprovalHandlers(
|
||||
const twoPhase = p.twoPhase === true;
|
||||
const timeoutMs =
|
||||
typeof p.timeoutMs === "number" ? p.timeoutMs : DEFAULT_EXEC_APPROVAL_TIMEOUT_MS;
|
||||
const explicitId = typeof p.id === "string" && p.id.trim().length > 0 ? p.id.trim() : null;
|
||||
const host = typeof p.host === "string" ? p.host.trim() : "";
|
||||
const nodeId = typeof p.nodeId === "string" ? p.nodeId.trim() : "";
|
||||
const explicitId = normalizeOptionalString(p.id) ?? null;
|
||||
const host = normalizeOptionalString(p.host) ?? "";
|
||||
const nodeId = normalizeOptionalString(p.nodeId) ?? "";
|
||||
const approvalContext = resolveSystemRunApprovalRequestContext({
|
||||
host,
|
||||
command: p.command,
|
||||
|
||||
@@ -19,7 +19,10 @@ import {
|
||||
resolveApnsAuthConfigFromEnv,
|
||||
resolveApnsRelayConfigFromEnv,
|
||||
} from "../../infra/push-apns.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "../../shared/string-coerce.js";
|
||||
import {
|
||||
buildCanvasScopedHostUrl,
|
||||
CANVAS_CAPABILITY_TTL_MS,
|
||||
@@ -126,8 +129,8 @@ function isForbiddenBrowserProxyMutation(params: unknown): boolean {
|
||||
return false;
|
||||
}
|
||||
const candidate = params as { method?: unknown; path?: unknown };
|
||||
const method = typeof candidate.method === "string" ? candidate.method.trim().toUpperCase() : "";
|
||||
const path = typeof candidate.path === "string" ? candidate.path.trim() : "";
|
||||
const method = (normalizeOptionalString(candidate.method) ?? "").toUpperCase();
|
||||
const path = normalizeOptionalString(candidate.path) ?? "";
|
||||
return Boolean(method && path && isPersistentBrowserProxyMutation(method, path));
|
||||
}
|
||||
|
||||
@@ -715,7 +718,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const { nodeId } = params as { nodeId: string };
|
||||
const id = String(nodeId ?? "").trim();
|
||||
const id = normalizeOptionalString(String(nodeId ?? "")) ?? "";
|
||||
if (!id) {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
|
||||
return;
|
||||
@@ -747,7 +750,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
});
|
||||
return;
|
||||
}
|
||||
const baseCanvasHostUrl = client?.canvasHostUrl?.trim() ?? "";
|
||||
const baseCanvasHostUrl = normalizeOptionalString(client?.canvasHostUrl) ?? "";
|
||||
if (!baseCanvasHostUrl) {
|
||||
respond(
|
||||
false,
|
||||
@@ -793,7 +796,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const nodeId = client?.connect?.device?.id ?? client?.connect?.client?.id;
|
||||
const trimmedNodeId = String(nodeId ?? "").trim();
|
||||
const trimmedNodeId = normalizeOptionalString(String(nodeId ?? "")) ?? "";
|
||||
if (!trimmedNodeId) {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
|
||||
return;
|
||||
@@ -824,13 +827,17 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const nodeId = client?.connect?.device?.id ?? client?.connect?.client?.id;
|
||||
const trimmedNodeId = String(nodeId ?? "").trim();
|
||||
const trimmedNodeId = normalizeOptionalString(String(nodeId ?? "")) ?? "";
|
||||
if (!trimmedNodeId) {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
|
||||
return;
|
||||
}
|
||||
const ackIds = Array.from(
|
||||
new Set((params.ids ?? []).map((value) => String(value ?? "").trim()).filter(Boolean)),
|
||||
new Set(
|
||||
(params.ids ?? [])
|
||||
.map((value) => normalizeOptionalString(String(value ?? "")) ?? "")
|
||||
.filter(Boolean),
|
||||
),
|
||||
);
|
||||
const remaining = ackPendingNodeActions(trimmedNodeId, ackIds);
|
||||
respond(
|
||||
@@ -859,8 +866,8 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
timeoutMs?: number;
|
||||
idempotencyKey: string;
|
||||
};
|
||||
const nodeId = String(p.nodeId ?? "").trim();
|
||||
const command = String(p.command ?? "").trim();
|
||||
const nodeId = normalizeOptionalString(String(p.nodeId ?? "")) ?? "";
|
||||
const command = normalizeOptionalString(String(p.command ?? "")) ?? "";
|
||||
if (!nodeId || !command) {
|
||||
respond(
|
||||
false,
|
||||
|
||||
@@ -19,6 +19,7 @@ import { fetchClawHubSkillDetail } from "../../infra/clawhub.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import { getRemoteSkillEligibility } from "../../infra/skills-remote.js";
|
||||
import { normalizeAgentId } from "../../routing/session-key.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { normalizeSecretInput } from "../../utils/normalize-secret-input.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
@@ -54,7 +55,7 @@ function collectSkillBins(entries: SkillEntry[]): string[] {
|
||||
for (const spec of install) {
|
||||
const specBins = spec?.bins ?? [];
|
||||
for (const bin of specBins) {
|
||||
const trimmed = String(bin).trim();
|
||||
const trimmed = normalizeOptionalString(String(bin)) ?? "";
|
||||
if (trimmed) {
|
||||
bins.add(trimmed);
|
||||
}
|
||||
@@ -78,7 +79,7 @@ export const skillsHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const cfg = loadConfig();
|
||||
const agentIdRaw = typeof params?.agentId === "string" ? params.agentId.trim() : "";
|
||||
const agentIdRaw = normalizeOptionalString(params?.agentId) ?? "";
|
||||
const agentId = agentIdRaw ? normalizeAgentId(agentIdRaw) : resolveDefaultAgentId(cfg);
|
||||
if (agentIdRaw) {
|
||||
const knownAgents = listAgentIds(cfg);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { ADMIN_SCOPE } from "../method-scopes.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
@@ -23,7 +24,7 @@ function resolveRequestedAgentIdOrRespondError(params: {
|
||||
respond: RespondFn;
|
||||
}) {
|
||||
const knownAgents = listAgentIds(params.cfg);
|
||||
const requestedAgentId = typeof params.rawAgentId === "string" ? params.rawAgentId.trim() : "";
|
||||
const requestedAgentId = normalizeOptionalString(params.rawAgentId) ?? "";
|
||||
if (!requestedAgentId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import {
|
||||
canonicalizeSpeechProviderId,
|
||||
getSpeechProvider,
|
||||
@@ -78,7 +79,7 @@ export const ttsHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
},
|
||||
"tts.convert": async ({ params, respond }) => {
|
||||
const text = typeof params.text === "string" ? params.text.trim() : "";
|
||||
const text = normalizeOptionalString(params.text) ?? "";
|
||||
if (!text) {
|
||||
respond(
|
||||
false,
|
||||
@@ -89,10 +90,10 @@ export const ttsHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
try {
|
||||
const cfg = loadConfig();
|
||||
const channel = typeof params.channel === "string" ? params.channel.trim() : undefined;
|
||||
const providerRaw = typeof params.provider === "string" ? params.provider.trim() : undefined;
|
||||
const modelId = typeof params.modelId === "string" ? params.modelId.trim() : undefined;
|
||||
const voiceId = typeof params.voiceId === "string" ? params.voiceId.trim() : undefined;
|
||||
const channel = normalizeOptionalString(params.channel);
|
||||
const providerRaw = normalizeOptionalString(params.provider);
|
||||
const modelId = normalizeOptionalString(params.modelId);
|
||||
const voiceId = normalizeOptionalString(params.voiceId);
|
||||
let overrides;
|
||||
try {
|
||||
overrides = resolveExplicitTtsOverrides({
|
||||
@@ -133,7 +134,7 @@ export const ttsHandlers: GatewayRequestHandlers = {
|
||||
"tts.setProvider": async ({ params, respond }) => {
|
||||
const cfg = loadConfig();
|
||||
const provider = canonicalizeSpeechProviderId(
|
||||
typeof params.provider === "string" ? params.provider.trim() : "",
|
||||
normalizeOptionalString(params.provider) ?? "",
|
||||
cfg,
|
||||
);
|
||||
if (!provider || !getSpeechProvider(provider, cfg)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { loadSessionStore, updateSessionStore } from "../config/sessions.js";
|
||||
import { parseSessionLabel } from "../sessions/session-label.js";
|
||||
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
type ErrorShape,
|
||||
@@ -56,11 +57,11 @@ export async function resolveSessionKeyFromResolveParams(params: {
|
||||
}): Promise<SessionsResolveResult> {
|
||||
const { cfg, p } = params;
|
||||
|
||||
const key = typeof p.key === "string" ? p.key.trim() : "";
|
||||
const key = normalizeOptionalString(p.key) ?? "";
|
||||
const hasKey = key.length > 0;
|
||||
const sessionId = typeof p.sessionId === "string" ? p.sessionId.trim() : "";
|
||||
const sessionId = normalizeOptionalString(p.sessionId) ?? "";
|
||||
const hasSessionId = sessionId.length > 0;
|
||||
const hasLabel = typeof p.label === "string" && p.label.trim().length > 0;
|
||||
const hasLabel = (normalizeOptionalString(p.label) ?? "").length > 0;
|
||||
const selectionCount = [hasKey, hasSessionId, hasLabel].filter(Boolean).length;
|
||||
if (selectionCount > 1) {
|
||||
return {
|
||||
|
||||
@@ -189,7 +189,7 @@ export async function handleToolsInvokeHttpRequest(
|
||||
}
|
||||
const body = (bodyUnknown ?? {}) as ToolsInvokeBody;
|
||||
|
||||
const toolName = typeof body.tool === "string" ? body.tool.trim() : "";
|
||||
const toolName = normalizeOptionalString(body.tool) ?? "";
|
||||
if (!toolName) {
|
||||
sendInvalidRequest(res, "tools.invoke requires body.tool");
|
||||
return true;
|
||||
@@ -212,7 +212,7 @@ export async function handleToolsInvokeHttpRequest(
|
||||
}
|
||||
}
|
||||
|
||||
const action = typeof body.action === "string" ? body.action.trim() : undefined;
|
||||
const action = normalizeOptionalString(body.action);
|
||||
|
||||
const argsRaw = body.args;
|
||||
const args =
|
||||
|
||||
Reference in New Issue
Block a user