From 29379ea0a641b8f1d90079b8b16c0218a5577535 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 24 Dec 2025 18:15:19 +0100 Subject: [PATCH] Fix thinking tag leakage by converting unsigned blocks to plain text Closes #302 --- packages/ai/CHANGELOG.md | 6 ++++++ packages/ai/src/providers/anthropic.ts | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index a9ecf1a4..05fecf5c 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] + +### Fixed + +- **Thinking tag leakage**: Fixed Claude mimicking literal `` tags in responses. Unsigned thinking blocks (from aborted streams) are now converted to plain text without `` tags. The TUI still displays them as thinking blocks. ([#302](https://github.com/badlogic/pi-mono/pull/302) by [@nicobailon](https://github.com/nicobailon)) + ## [0.25.1] - 2025-12-21 ### Added diff --git a/packages/ai/src/providers/anthropic.ts b/packages/ai/src/providers/anthropic.ts index 1edb726f..f031fe09 100644 --- a/packages/ai/src/providers/anthropic.ts +++ b/packages/ai/src/providers/anthropic.ts @@ -463,11 +463,12 @@ function convertMessages(messages: Message[], model: Model<"anthropic-messages"> } else if (block.type === "thinking") { if (block.thinking.trim().length === 0) continue; // If thinking signature is missing/empty (e.g., from aborted stream), - // convert to text block to avoid API rejection + // convert to plain text block without tags to avoid API rejection + // and prevent Claude from mimicking the tags in responses if (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) { blocks.push({ type: "text", - text: sanitizeSurrogates(`\n${block.thinking}\n`), + text: sanitizeSurrogates(block.thinking), }); } else { blocks.push({