From 222562ecb2a3e9847d121f63a7edb94e371e4a0b Mon Sep 17 00:00:00 2001 From: can1357 Date: Tue, 16 Jun 2026 14:31:23 +0200 Subject: [PATCH] test(ai): cover renderDelimitedThinking literal-envelope unwrap Adds render-layer regression coverage in packages/ai, where the #2702 fix lives. Asserts the anthropic dialect unwraps a single literal envelope (no nesting), unwraps sibling envelopes independently (no malformed close/open boundary), and that a envelope is not mistaken for the qwen3 delimiter (prefix safety). The PR's existing test lives only in packages/coding-agent and cannot exercise the fix under the shared workspace node_modules symlink. Addresses review feedback on #2702. --- packages/ai/test/transcript-render.test.ts | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/ai/test/transcript-render.test.ts b/packages/ai/test/transcript-render.test.ts index eff7dd4bc..c76f0ecaf 100644 --- a/packages/ai/test/transcript-render.test.ts +++ b/packages/ai/test/transcript-render.test.ts @@ -93,4 +93,50 @@ describe("dialect transcript rendering", () => { expect(new Set(outputs).size).toBe(outputs.length); }); + + it("does not double-wrap thinking blocks already stored with literal envelopes", () => { + const wrapped: Message[] = [ + { + role: "assistant", + content: [{ type: "thinking", thinking: "\nCheck logs first.\n" }], + api: "mock", + provider: "mock", + model: "mock", + usage: usage(), + stopReason: "stop", + timestamp: 1, + }, + ]; + + // Anthropic dialect must unwrap the literal envelope instead of nesting a second one. + const anthropic = getDialectDefinition("anthropic").renderTranscript(wrapped); + expect(anthropic).toContain("Assistant: \nCheck logs first.\n"); + expect(anthropic).not.toContain("\n"); + + // A envelope must not be confused with the qwen3 delimiter (prefix safety). + const qwen3 = getDialectDefinition("qwen3").renderTranscript(wrapped); + expect(qwen3).toContain("\n\nCheck logs first.\n\n"); + }); + + it("unwraps sibling literal thinking envelopes independently", () => { + const siblings: Message[] = [ + { + role: "assistant", + content: [ + { type: "thinking", thinking: "\nfirst\n\n\nsecond\n" }, + ], + api: "mock", + provider: "mock", + model: "mock", + usage: usage(), + stopReason: "stop", + timestamp: 1, + }, + ]; + + // Each literal envelope is unwrapped on its own; no malformed close/open boundary leaks through. + const out = getDialectDefinition("anthropic").renderTranscript(siblings); + expect(out).toContain("Assistant: \nfirst\nsecond\n"); + expect(out).not.toContain("first\n\n\nsecond"); + }); });