




















@@ -2,7 +2,6 @@
22// used to decide whether repeated tool actions can recover prior failures.
33import { describe, expect, it } from "vitest";
44import {
5-buildToolActionFingerprint,
65buildToolMutationState,
76isLikelyMutatingToolName,
87isMutatingToolCall,
@@ -22,21 +21,23 @@ describe("tool mutation helpers", () => {
2221});
23222423it("builds stable fingerprints for mutating calls and omits read-only calls", () => {
25-const writeFingerprint = buildToolActionFingerprint(
24+const writeFingerprint = buildToolMutationState(
2625"write",
2726{ path: "/tmp/demo.txt", id: 42 },
2827"write /tmp/demo.txt",
29-);
28+).actionFingerprint;
3029expect(writeFingerprint).toBe("tool=write|path=/tmp/demo.txt|id=42");
313032-const metaOnlyFingerprint = buildToolActionFingerprint(
31+const metaOnlyFingerprint = buildToolMutationState(
3332"exec",
3433{ command: "npm start" },
3534"npm start",
36-);
35+).actionFingerprint;
3736expect(metaOnlyFingerprint).toBe("tool=exec|meta=npm start");
383739-const readFingerprint = buildToolActionFingerprint("read", { path: "/tmp/demo.txt" });
38+const readFingerprint = buildToolMutationState("read", {
39+path: "/tmp/demo.txt",
40+}).actionFingerprint;
4041expect(readFingerprint).toBeUndefined();
4142});
4243@@ -49,7 +50,7 @@ describe("tool mutation helpers", () => {
4950])("treats read-only shell command as non-mutating: %s %s", (toolName, command) => {
5051expect(isMutatingToolCall(toolName, { command })).toBe(false);
5152expect(buildToolMutationState(toolName, { command }).mutatingAction).toBe(false);
52-expect(buildToolActionFingerprint(toolName, { command }, command)).toBeUndefined();
53+expect(buildToolMutationState(toolName, { command }, command).actionFingerprint).toBeUndefined();
5354});
54555556it.each([
@@ -101,22 +102,22 @@ describe("tool mutation helpers", () => {
101102])("keeps ambiguous or mutating shell command mutating: %s %s", (toolName, command) => {
102103expect(isMutatingToolCall(toolName, { command })).toBe(true);
103104expect(buildToolMutationState(toolName, { command }, command).mutatingAction).toBe(true);
104-expect(buildToolActionFingerprint(toolName, { command }, command)).toBe(
105+expect(buildToolMutationState(toolName, { command }, command).actionFingerprint).toBe(
105106`tool=${toolName}|meta=${command.toLowerCase().replace(/\s+/g, " ")}`,
106107);
107108});
108109109110it("treats coding-tool path aliases as the same stable target", () => {
110-const filePathFingerprint = buildToolActionFingerprint("edit", {
111+const filePathFingerprint = buildToolMutationState("edit", {
111112file_path: "/tmp/demo.txt",
112113old_string: "before",
113114new_string: "after",
114-});
115-const fileAliasFingerprint = buildToolActionFingerprint("edit", {
115+}).actionFingerprint;
116+const fileAliasFingerprint = buildToolMutationState("edit", {
116117file: "/tmp/demo.txt",
117118oldText: "before",
118119newText: "after again",
119-});
120+}).actionFingerprint;
120121121122expect(filePathFingerprint).toBe("tool=edit|path=/tmp/demo.txt");
122123expect(fileAliasFingerprint).toBe("tool=edit|path=/tmp/demo.txt");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。