fix: keep tool detail redaction canonical

This commit is contained in:
Peter Steinberger
2026-06-01 00:49:24 +01:00
parent 37d79a4303
commit 219d854178
6 changed files with 46 additions and 9 deletions

View File

@@ -3,7 +3,7 @@ import {
normalizeOptionalString,
} from "@openclaw/normalization-core/string-coerce";
import { parseStrictFiniteNumber } from "../infra/parse-finite-number.js";
import { redactToolDetail } from "../logging/redact.js";
import { redactToolPayloadText } from "../logging/redact.js";
import { resolveExecDetail, type ToolDetailMode } from "./tool-display-exec.js";
import { asRecord } from "./tool-display-record.js";
@@ -121,7 +121,7 @@ function coerceDisplayValue(
if (!rawLine) {
return undefined;
}
const firstLine = redactToolDetail(rawLine);
const firstLine = redactToolPayloadText(rawLine);
if (firstLine.length > maxStringChars) {
const half = Math.floor((maxStringChars - 1) / 2);
return `${firstLine.slice(0, half)}${firstLine.slice(-(maxStringChars - 1 - half))}`;

View File

@@ -1,4 +1,4 @@
import { redactToolDetail } from "../logging/redact.js";
import { redactToolPayloadText } from "../logging/redact.js";
import {
binaryName,
firstPositional,
@@ -427,7 +427,7 @@ function isGenericSummary(summary: string): boolean {
}
function compactRawCommand(raw: string, maxLength = 120): string {
const oneLine = redactToolDetail(
const oneLine = redactToolPayloadText(
raw
.replace(/\s*\n\s*/g, " ")
.replace(/\s{2,}/g, " ")

View File

@@ -532,6 +532,15 @@ describe("compactRawCommand middle truncation", () => {
// The sk- prefixed token must be redacted (masked) before truncation
expect(result).not.toContain("ABCDEFGHIJKLMNOP1234567890abcdefghij");
});
it("uses the canonical tool payload redactor before compacting raw commands", () => {
const longCommand =
"/opt/custom/bin/deploy --aws-key AKIDABCDEFGHIJKLMNOP1234567890 --output /data/results/deploy-output.json";
const result = resolveExecDetail({ command: longCommand });
expect(result).not.toContain("AKIDABCDEFGHIJKLMNOP1234567890");
expect(result).toContain("AKIDAB…7890");
});
});
describe("coerceDisplayValue middle truncation", () => {
@@ -582,4 +591,20 @@ describe("coerceDisplayValue middle truncation", () => {
// The ghp_ token must be redacted before truncation
expect(detail).not.toContain("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop");
});
it("uses the canonical tool payload redactor before compacting string details", () => {
const longValue =
"Deploying with AWS key AKIDABCDEFGHIJKLMNOP1234567890 and " +
"x".repeat(200) +
" final-step";
const detail = formatToolDetail(
resolveToolDisplay({
name: "sessions_spawn",
args: { task: longValue },
}),
);
expect(detail).not.toContain("AKIDABCDEFGHIJKLMNOP1234567890");
expect(detail).toContain("AKIDAB…7890");
});
});

View File

@@ -1,7 +1,11 @@
import type { UpdateAvailable } from "../infra/update-startup.js";
export const GATEWAY_EVENT_UPDATE_AVAILABLE = "update.available" as const;
export type GatewayUpdateAvailableEventPayload = {
updateAvailable: UpdateAvailable | null;
export type UpdateAvailableEventData = {
currentVersion: string;
latestVersion: string;
channel: string;
};
export type GatewayUpdateAvailableEventPayload = {
updateAvailable: UpdateAvailableEventData | null;
};

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { redactToolDetail } from "./browser-redact.ts";
import { redactToolDetail, redactToolPayloadText } from "./browser-redact.ts";
describe("browser tool detail redaction", () => {
it("redacts tool detail credential families without Node config imports", () => {
@@ -29,4 +29,10 @@ describe("browser tool detail redaction", () => {
expect(redacted).not.toContain("abc123");
expect(redacted).not.toContain("verySensitiveCookieValue");
});
it("exposes the tool payload redaction name used by shared display modules", () => {
expect(redactToolPayloadText("OPENAI_API_KEY=sk-1234567890abcdef")).toBe(
"OPENAI_API_KEY=sk-123...cdef",
);
});
});

View File

@@ -74,3 +74,5 @@ export function redactToolDetail(detail: string): string {
}
return redacted;
}
export const redactToolPayloadText = redactToolDetail;