Files
openclaw/src/agents/tool-error-summary.ts
RenzoMXD 8fb22fdfe2 fix(agents): compare file-target structurally not via fingerprint split
Address clawsweeper P2 on PR #79067: the prior cross-tool recovery
extracted the path target by splitting the joined fingerprint string
on `|`, which is also a legal character in file paths. A failed edit on
`/tmp/a|left` and a successful write to `/tmp/a|right` would both
extract as `path=/tmp/a` and incorrectly clear the prior failure.

Carry a structured `fileTarget: { path?, oldpath? }` alongside the
existing `actionFingerprint` string and compare it directly.
`extractFileTarget` reads args once at fingerprint-build time, with
the same alias support as `buildToolActionFingerprint`. The
fingerprint string is unchanged for diagnostics and the exact-equality
match path; only the cross-tool fallback now compares structurally.

Threaded through `ToolMutationState`, `ToolActionRef`, `ToolCallSummary`,
and `ToolErrorSummary` so the existing handler code at
`pi-embedded-subscribe.handlers.tools.ts:910-928` can populate and
consume it without re-parsing.

Adds delimiter-bearing-path regression test asserting that
`/tmp/a|left` vs `/tmp/a|right` returns false, and that an identical
delimiter-bearing path on both sides still matches.
2026-05-08 07:00:00 -04:00

19 lines
541 B
TypeScript

import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import type { FileTarget } from "./tool-mutation.js";
export type ToolErrorSummary = {
toolName: string;
meta?: string;
error?: string;
timedOut?: boolean;
mutatingAction?: boolean;
actionFingerprint?: string;
fileTarget?: FileTarget;
};
const EXEC_LIKE_TOOL_NAMES = new Set(["exec", "bash"]);
export function isExecLikeToolName(toolName: string): boolean {
return EXEC_LIKE_TOOL_NAMES.has(normalizeOptionalLowercaseString(toolName) ?? "");
}