Files
openclaw/extensions/codex/src/app-server/tool-progress-normalization.ts
T
Peter Steinberger 26210c1600 refactor: remove browser and codex dead exports (#105867)
* refactor(browser): collapse Playwright export paths

* refactor(browser): remove dead plugin exports

* refactor(codex): remove dead app-server exports

* refactor(codex): remove remaining dead exports

* test(codex): use canonical private-type owners

* test(browser): isolate proxy startup state

* test(browser): remove stale chrome imports

* refactor(codex): privatize remaining helpers

* chore(deadcode): refresh export baseline after rebase

* refactor(browser): finish canonical helper ownership

* refactor: fix dead-export cleanup gates

* refactor(codex): keep runtime facades LOC-neutral

* chore(ci): refresh TypeScript LOC baseline

* chore(deadcode): refresh ratchets after rebase

* chore(ci): refresh LOC baseline after main advance

* chore(deadcode): align ratchets with latest main
2026-07-12 22:23:11 -07:00

85 lines
2.8 KiB
TypeScript

/**
* Normalizes and sanitizes Codex dynamic-tool progress payloads before they are
* emitted into OpenClaw events or logs.
*/
import {
inferToolMetaFromArgs,
type EmbeddedRunAttemptParams,
type ToolProgressDetailMode,
} from "openclaw/plugin-sdk/agent-harness-runtime";
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
import {
isJsonObject,
type CodexDynamicToolCallParams,
type CodexDynamicToolCallResponse,
type JsonValue,
} from "./protocol.js";
/** Maps OpenClaw tool-progress config to the mode used by Codex progress metadata. */
export function resolveCodexToolProgressDetailMode(
value: EmbeddedRunAttemptParams["toolProgressDetail"],
): ToolProgressDetailMode {
return value === "raw" ? "raw" : "explain";
}
/** Recursively redacts sensitive strings and handles circular values in event payloads. */
function sanitizeCodexAgentEventValue(value: unknown, seen = new WeakSet<object>()): unknown {
if (typeof value === "string") {
return redactToolPayloadText(value);
}
if (Array.isArray(value)) {
if (seen.has(value)) {
return "[Circular]";
}
seen.add(value);
return value.map((entry) => sanitizeCodexAgentEventValue(entry, seen));
}
if (value && typeof value === "object") {
if (seen.has(value)) {
return "[Circular]";
}
seen.add(value);
const out: Record<string, unknown> = {};
for (const [key, child] of Object.entries(value as Record<string, unknown>)) {
out[key] =
typeof child === "string"
? redactSensitiveFieldValue(key, child)
: sanitizeCodexAgentEventValue(child, seen);
}
return out;
}
return value;
}
/** Sanitizes a record-shaped Codex agent event payload. */
export function sanitizeCodexAgentEventRecord(
value: Record<string, unknown>,
): Record<string, unknown> {
return sanitizeCodexAgentEventValue(value) as Record<string, unknown>;
}
/** Sanitizes dynamic-tool arguments before diagnostic/event emission. */
export function sanitizeCodexToolArguments(
value: JsonValue | undefined,
): Record<string, unknown> | undefined {
if (!isJsonObject(value)) {
return undefined;
}
return sanitizeCodexAgentEventRecord(value);
}
/** Sanitizes a Codex dynamic-tool response before diagnostic/event emission. */
export function sanitizeCodexToolResponse(
response: CodexDynamicToolCallResponse,
): Record<string, unknown> {
return sanitizeCodexAgentEventRecord(response as unknown as Record<string, unknown>);
}
/** Infers compact human-readable tool metadata from Codex dynamic-tool arguments. */
export function inferCodexDynamicToolMeta(
call: Pick<CodexDynamicToolCallParams, "tool" | "arguments">,
detailMode: ToolProgressDetailMode,
): string | undefined {
return inferToolMetaFromArgs(call.tool, call.arguments, { detailMode });
}