From 3ed4b69b3840020a9f76af8b16b8ee2250666b15 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 20 Apr 2026 17:21:02 +0100 Subject: [PATCH] test: share agent tool call id fixtures --- src/agents/tool-call-id.test.ts | 171 ++++++++++++++------------------ 1 file changed, 75 insertions(+), 96 deletions(-) diff --git a/src/agents/tool-call-id.test.ts b/src/agents/tool-call-id.test.ts index 8bc577c0753..e85f2e1cf32 100644 --- a/src/agents/tool-call-id.test.ts +++ b/src/agents/tool-call-id.test.ts @@ -29,7 +29,35 @@ const buildDuplicateIdCollisionInput = () => }, ]); -const buildRepeatedRawIdInput = () => +const readToolCall = (id: string) => ({ + type: "toolCall" as const, + id, + name: "read", + arguments: {}, +}); + +const buildToolResult = (params: { + toolCallId: string; + text: string; + toolName?: string; + toolUseId?: string; +}) => ({ + role: "toolResult" as const, + toolCallId: params.toolCallId, + ...(params.toolUseId ? { toolUseId: params.toolUseId } : {}), + toolName: params.toolName ?? "read", + content: [{ type: "text" as const, text: params.text }], +}); + +const signedReadAssistant = (signature: string, id: string) => ({ + role: "assistant" as const, + content: [ + { type: "thinking" as const, thinking: "internal", thinkingSignature: signature }, + readToolCall(id), + ], +}); + +const buildRepeatedEditIdInput = (params: { includeToolUseId?: boolean } = {}) => castAgentMessages([ { role: "assistant", @@ -38,44 +66,24 @@ const buildRepeatedRawIdInput = () => { type: "toolCall", id: "edit:22", name: "edit", arguments: {} }, ], }, - { - role: "toolResult", + buildToolResult({ toolCallId: "edit:22", toolName: "edit", - content: [{ type: "text", text: "one" }], - }, - { - role: "toolResult", + ...(params.includeToolUseId ? { toolUseId: "edit:22" } : {}), + text: "one", + }), + buildToolResult({ toolCallId: "edit:22", toolName: "edit", - content: [{ type: "text", text: "two" }], - }, + ...(params.includeToolUseId ? { toolUseId: "edit:22" } : {}), + text: "two", + }), ]); +const buildRepeatedRawIdInput = () => buildRepeatedEditIdInput(); + const buildRepeatedSharedToolResultIdInput = () => - castAgentMessages([ - { - role: "assistant", - content: [ - { type: "toolCall", id: "edit:22", name: "edit", arguments: {} }, - { type: "toolCall", id: "edit:22", name: "edit", arguments: {} }, - ], - }, - { - role: "toolResult", - toolCallId: "edit:22", - toolUseId: "edit:22", - toolName: "edit", - content: [{ type: "text", text: "one" }], - }, - { - role: "toolResult", - toolCallId: "edit:22", - toolUseId: "edit:22", - toolName: "edit", - content: [{ type: "text", text: "two" }], - }, - ]); + buildRepeatedEditIdInput({ includeToolUseId: true }); function expectCollisionIdsRemainDistinct( out: AgentMessage[], @@ -111,6 +119,29 @@ function expectSingleToolCallRewrite( expect(result.toolCallId).toBe(toolCall.id); } +function expectToolUseIdsFollowDistinctToolCallIds( + out: AgentMessage[], + mode: "strict" | "strict9", +): { aId: string; bId: string } { + const ids = expectCollisionIdsRemainDistinct(out, mode); + const r1 = out[1] as Extract & { toolUseId?: string }; + const r2 = out[2] as Extract & { toolUseId?: string }; + expect(r1.toolUseId).toBe(ids.aId); + expect(r2.toolUseId).toBe(ids.bId); + return ids; +} + +function expectStrict9IdLengths(ids: { aId: string; bId: string }) { + expect(ids.aId.length).toBe(9); + expect(ids.bId.length).toBe(9); +} + +function expectDistinctStrict9Ids(out: AgentMessage[], input: AgentMessage[]) { + expect(out).not.toBe(input); + const ids = expectCollisionIdsRemainDistinct(out, "strict9"); + expectStrict9IdLengths(ids); +} + function expectReplaySafeSignedTurnOwnership(params: { input: AgentMessage[]; preservedTurn: "first" | "second"; @@ -199,11 +230,7 @@ describe("sanitizeToolCallIdsForCloudCodeAssist", () => { const out = sanitizeToolCallIdsForCloudCodeAssist(input); expect(out).not.toBe(input); - const { aId, bId } = expectCollisionIdsRemainDistinct(out, "strict"); - const r1 = out[1] as Extract & { toolUseId?: string }; - const r2 = out[2] as Extract & { toolUseId?: string }; - expect(r1.toolUseId).toBe(aId); - expect(r2.toolUseId).toBe(bId); + expectToolUseIdsFollowDistinctToolCallIds(out, "strict"); }); it("assigns distinct IDs when identical raw tool call ids repeat", () => { @@ -362,27 +389,11 @@ describe("sanitizeToolCallIdsForCloudCodeAssist", () => { const input = castAgentMessages([ { role: "assistant", - content: [{ type: "toolCall", id: "call_1", name: "read", arguments: {} }], - }, - { - role: "toolResult", - toolCallId: "call_1", - toolName: "read", - content: [{ type: "text", text: "first" }], - }, - { - role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "call1", name: "read", arguments: {} }, - ], - }, - { - role: "toolResult", - toolCallId: "call1", - toolName: "read", - content: [{ type: "text", text: "second" }], + content: [readToolCall("call_1")], }, + buildToolResult({ toolCallId: "call_1", text: "first" }), + signedReadAssistant("sig_1", "call1"), + buildToolResult({ toolCallId: "call1", text: "second" }), ]); const out = sanitizeToolCallIdsForCloudCodeAssist(input, "strict", { @@ -404,32 +415,10 @@ describe("sanitizeToolCallIdsForCloudCodeAssist", () => { it("rewrites later signed turns when an earlier signed turn already owns the raw id", () => { const input = castAgentMessages([ - { - role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "call1", name: "read", arguments: {} }, - ], - }, - { - role: "toolResult", - toolCallId: "call1", - toolName: "read", - content: [{ type: "text", text: "first" }], - }, - { - role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_2" }, - { type: "toolCall", id: "call1", name: "read", arguments: {} }, - ], - }, - { - role: "toolResult", - toolCallId: "call1", - toolName: "read", - content: [{ type: "text", text: "second" }], - }, + signedReadAssistant("sig_1", "call1"), + buildToolResult({ toolCallId: "call1", text: "first" }), + signedReadAssistant("sig_2", "call1"), + buildToolResult({ toolCallId: "call1", text: "second" }), ]); expectReplaySafeSignedTurnOwnership({ @@ -504,20 +493,14 @@ describe("sanitizeToolCallIdsForCloudCodeAssist", () => { ]); const out = sanitizeToolCallIdsForCloudCodeAssist(input, "strict9"); - expect(out).not.toBe(input); - const { aId, bId } = expectCollisionIdsRemainDistinct(out, "strict9"); - expect(aId.length).toBe(9); - expect(bId.length).toBe(9); + expectDistinctStrict9Ids(out, input); }); it("assigns distinct strict9 IDs when identical raw tool call ids repeat", () => { const input = buildRepeatedRawIdInput(); const out = sanitizeToolCallIdsForCloudCodeAssist(input, "strict9"); - expect(out).not.toBe(input); - const { aId, bId } = expectCollisionIdsRemainDistinct(out, "strict9"); - expect(aId.length).toBe(9); - expect(bId.length).toBe(9); + expectDistinctStrict9Ids(out, input); }); it("reuses one rewritten strict9 id when a tool result carries matching toolCallId and toolUseId", () => { @@ -525,11 +508,7 @@ describe("sanitizeToolCallIdsForCloudCodeAssist", () => { const out = sanitizeToolCallIdsForCloudCodeAssist(input, "strict9"); expect(out).not.toBe(input); - const { aId, bId } = expectCollisionIdsRemainDistinct(out, "strict9"); - const r1 = out[1] as Extract & { toolUseId?: string }; - const r2 = out[2] as Extract & { toolUseId?: string }; - expect(r1.toolUseId).toBe(aId); - expect(r2.toolUseId).toBe(bId); + expectStrict9IdLengths(expectToolUseIdsFollowDistinctToolCallIds(out, "strict9")); }); }); });