refactor: consolidate coercion contracts (#122458)

* refactor: consolidate coercion contracts

Centralize exact string, record, numeric, date, Boolean, argument, and structured-error coercions while preserving call-site semantics.

Migrate canonical-name collisions and deprecated internal SDK bypasses, deleting 55 net production/tooling lines. Expand declaration ownership enforcement to 101 allowed helpers and add a narrow export-completeness audit.

* fix: preserve standalone script coercions

Keep copied Control UI tooling self-contained and retain the trusted release harness module-relative source seam when the harness runs against an old target cwd.
This commit is contained in:
Peter Steinberger
2026-08-11 23:26:37 -07:00
committed by GitHub
parent 66fe424590
commit b080dd1e76
276 changed files with 1685 additions and 1663 deletions
+10 -17
View File
@@ -1,4 +1,5 @@
/** Auto-reply dispatch orchestration, hook composition, and foreground delivery fencing. */
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import { normalizeChatType } from "../channels/chat-type.js";
import { isChannelPartialDeliveryError } from "../channels/turn/delivery-result.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
@@ -76,25 +77,17 @@ function applyRuntimeToolsAllow(
};
}
function normalizeForegroundReplyFencePart(value: unknown): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const trimmed = value.trim();
return trimmed.length > 0 ? trimmed : undefined;
}
function resolveForegroundReplyFenceKey(finalized: FinalizedMsgContext): string | undefined {
const sessionKey = normalizeForegroundReplyFencePart(finalized.SessionKey);
const sessionKey = normalizeOptionalString(finalized.SessionKey);
const channel =
normalizeForegroundReplyFencePart(finalized.OriginatingChannel) ??
normalizeForegroundReplyFencePart(finalized.Surface) ??
normalizeForegroundReplyFencePart(finalized.Provider);
normalizeOptionalString(finalized.OriginatingChannel) ??
normalizeOptionalString(finalized.Surface) ??
normalizeOptionalString(finalized.Provider);
const target =
normalizeForegroundReplyFencePart(finalized.OriginatingTo) ??
normalizeForegroundReplyFencePart(finalized.NativeChannelId) ??
normalizeForegroundReplyFencePart(finalized.From) ??
normalizeForegroundReplyFencePart(finalized.To);
normalizeOptionalString(finalized.OriginatingTo) ??
normalizeOptionalString(finalized.NativeChannelId) ??
normalizeOptionalString(finalized.From) ??
normalizeOptionalString(finalized.To);
if (!sessionKey || !channel || !target) {
return undefined;
@@ -104,7 +97,7 @@ function resolveForegroundReplyFenceKey(finalized: FinalizedMsgContext): string
return JSON.stringify([
"foreground",
channel,
normalizeForegroundReplyFencePart(finalized.AccountId) ?? "default",
normalizeOptionalString(finalized.AccountId) ?? "default",
sessionKey,
normalizeChatType(finalized.ChatType) ?? "unknown",
target,
+5 -6
View File
@@ -1,5 +1,8 @@
import { asPositiveFiniteNumber as normalizePairingQrExpiresAtMs } from "@openclaw/normalization-core/number-coercion";
import { readNonBlankString as normalizeTtsSupplementSpokenText } from "@openclaw/normalization-core/string-coerce";
import {
readNonBlankString,
readNonBlankString as normalizeTtsSupplementSpokenText,
} from "@openclaw/normalization-core/string-coerce";
import type { OutboundLocation } from "../channels/location.js";
/** Reply payload contracts and metadata helpers shared by dispatch and channel renderers. */
import type { ReplyToMode } from "../config/types.base.js";
@@ -117,10 +120,6 @@ type PairingQrReplyChannelData = {
expiresAtMs: number;
};
function normalizePairingQrSetupCode(value: unknown): string | undefined {
return typeof value === "string" && value.trim() ? value : undefined;
}
export function readPairingQrReplyChannelData(
payload: Pick<ReplyPayload, "channelData">,
): PairingQrReplyChannelData | undefined {
@@ -129,7 +128,7 @@ export function readPairingQrReplyChannelData(
return undefined;
}
const record = raw as Record<string, unknown>;
const setupCode = normalizePairingQrSetupCode(record.setupCode);
const setupCode = readNonBlankString(record.setupCode);
const expiresAtMs = normalizePairingQrExpiresAtMs(record.expiresAtMs);
return setupCode && expiresAtMs ? { setupCode, expiresAtMs } : undefined;
}