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 -18
View File
@@ -2,7 +2,7 @@
* Lists and normalizes models exposed by the Codex app-server `model/list`
* endpoint, including pagination and shared-client lease handling.
*/
import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
import type {
CodexAppServerAuthRequirement,
resolveCodexAppServerAuthProfileIdForAgent,
@@ -145,8 +145,8 @@ export function readModelListResult(value: unknown): CodexAppServerModelListResu
}
function readCodexModel(value: CodexModel): CodexAppServerModel {
const id = readNonEmptyString(value.id);
const model = readNonEmptyString(value.model);
const id = normalizeOptionalString(value.id);
const model = normalizeOptionalString(value.model);
if (!id || !model) {
throw new Error(
"Invalid Codex app-server model/list response: model id and name must be non-empty strings",
@@ -155,37 +155,29 @@ function readCodexModel(value: CodexModel): CodexAppServerModel {
return {
id,
model,
...(readNonEmptyString(value.displayName)
? { displayName: readNonEmptyString(value.displayName) }
...(normalizeOptionalString(value.displayName)
? { displayName: normalizeOptionalString(value.displayName) }
: {}),
...(readNonEmptyString(value.description)
? { description: readNonEmptyString(value.description) }
...(normalizeOptionalString(value.description)
? { description: normalizeOptionalString(value.description) }
: {}),
hidden: value.hidden,
isDefault: value.isDefault,
inputModalities: value.inputModalities,
supportedReasoningEfforts: readReasoningEfforts(value.supportedReasoningEfforts),
...(readNonEmptyString(value.defaultReasoningEffort)
? { defaultReasoningEffort: readNonEmptyString(value.defaultReasoningEffort) }
...(normalizeOptionalString(value.defaultReasoningEffort)
? { defaultReasoningEffort: normalizeOptionalString(value.defaultReasoningEffort) }
: {}),
};
}
function readReasoningEfforts(value: CodexReasoningEffortOption[]): string[] {
const efforts = value
.map((entry) => readNonEmptyString(entry.reasoningEffort))
.map((entry) => normalizeOptionalString(entry.reasoningEffort))
.filter((entry): entry is string => entry !== undefined);
return uniqueStrings(efforts);
}
function readNonEmptyString(value: unknown): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const trimmed = value.trim();
return trimmed || undefined;
}
function normalizeMaxPages(value: unknown): number {
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 20;
}