From faae37d38c90d1dd57e1ff67597f007a58c41416 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 12 Apr 2026 11:09:17 +0100 Subject: [PATCH] test(agents): share validate turns helpers --- ...pi-embedded-helpers.validate-turns.test.ts | 66 ++++++++----------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/src/agents/pi-embedded-helpers.validate-turns.test.ts b/src/agents/pi-embedded-helpers.validate-turns.test.ts index 01eb27e32ed..9e20ad0d48f 100644 --- a/src/agents/pi-embedded-helpers.validate-turns.test.ts +++ b/src/agents/pi-embedded-helpers.validate-turns.test.ts @@ -32,6 +32,21 @@ function makeDualToolAnthropicTurns(nextUserContent: unknown[]) { ]); } +function makeSignedThinkingGatewayToolCall(toolId: string) { + return [ + { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, + { type: "toolCall", id: toolId, name: "gateway", arguments: {} }, + ]; +} + +function expectAssistantToolCallsOmitted(result: AgentMessage[], expectedLength: number) { + expect(result).toHaveLength(expectedLength); + expect((result[1] as { role?: unknown }).role).toBe("assistant"); + expect((result[1] as { content?: unknown[] }).content).toEqual([ + { type: "text", text: "[tool calls omitted]" }, + ]); +} + describe("validate turn edge cases", () => { it("returns empty array unchanged", () => { expect(validateGeminiTurns([])).toEqual([]); @@ -530,10 +545,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { { role: "user", content: [{ type: "text", text: "Use tool" }] }, { role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "tool-1", name: "gateway", arguments: {} }, - ], + content: makeSignedThinkingGatewayToolCall("tool-1"), }, { role: "toolResult", @@ -549,10 +561,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { expect(result).toHaveLength(4); const assistantContent = (result[1] as { content?: unknown[] }).content; - expect(assistantContent).toEqual([ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "tool-1", name: "gateway", arguments: {} }, - ]); + expect(assistantContent).toEqual(makeSignedThinkingGatewayToolCall("tool-1")); }); it("drops signed-thinking turns when the only matching tool result is embedded in user content", () => { @@ -561,7 +570,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { { role: "assistant", content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, + makeSignedThinkingGatewayToolCall("tool-1")[0], { type: "toolUse", id: "tool-1", name: "gateway", arguments: {} }, ], }, @@ -576,11 +585,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { const result = validateAnthropicTurns(msgs); - expect(result).toHaveLength(3); - expect((result[1] as { role?: unknown }).role).toBe("assistant"); - expect((result[1] as { content?: unknown[] }).content).toEqual([ - { type: "text", text: "[tool calls omitted]" }, - ]); + expectAssistantToolCallsOmitted(result, 3); }); it("preserves signed-thinking turns when a trusted tool result carries both stale and current id aliases", () => { @@ -588,10 +593,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { { role: "user", content: [{ type: "text", text: "Use tool" }] }, { role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "tool-current", name: "gateway", arguments: {} }, - ], + content: makeSignedThinkingGatewayToolCall("tool-current"), }, { role: "toolResult", @@ -607,10 +609,9 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { const result = validateAnthropicTurns(msgs); expect(result).toHaveLength(4); - expect((result[1] as { content?: unknown[] }).content).toEqual([ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "tool-current", name: "gateway", arguments: {} }, - ]); + expect((result[1] as { content?: unknown[] }).content).toEqual( + makeSignedThinkingGatewayToolCall("tool-current"), + ); }); it("drops signed-thinking turns whose sibling tool calls are dangling", () => { @@ -618,21 +619,14 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { { role: "user", content: [{ type: "text", text: "Use tool" }] }, { role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "tool-1", name: "gateway", arguments: {} }, - ], + content: makeSignedThinkingGatewayToolCall("tool-1"), }, { role: "user", content: [{ type: "text", text: "Continue" }] }, ]); const result = validateAnthropicTurns(msgs); - expect(result).toHaveLength(3); - expect((result[1] as { role?: unknown }).role).toBe("assistant"); - expect((result[1] as { content?: unknown[] }).content).toEqual([ - { type: "text", text: "[tool calls omitted]" }, - ]); + expectAssistantToolCallsOmitted(result, 3); }); it("does not trust future tool results with the right id but the wrong tool name", () => { @@ -640,10 +634,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { { role: "user", content: [{ type: "text", text: "Use tool" }] }, { role: "assistant", - content: [ - { type: "thinking", thinking: "internal", thinkingSignature: "sig_1" }, - { type: "toolCall", id: "tool-1", name: "gateway", arguments: {} }, - ], + content: makeSignedThinkingGatewayToolCall("tool-1"), }, { role: "toolResult", @@ -657,10 +648,7 @@ describe("validateAnthropicTurns strips dangling tool_use blocks", () => { const result = validateAnthropicTurns(msgs); - expect(result).toHaveLength(4); - expect((result[1] as { content?: unknown[] }).content).toEqual([ - { type: "text", text: "[tool calls omitted]" }, - ]); + expectAssistantToolCallsOmitted(result, 4); }); it("drops redacted-thinking turns whose sibling tool calls are dangling", () => {