From 2c8842f87cf5750a31211c9140897ad6a504c6a1 Mon Sep 17 00:00:00 2001 From: Juan Camilo Date: Tue, 7 Apr 2026 11:50:41 +0200 Subject: [PATCH] test: align resume stripping expectation with orphan-thinking filter --- src/utils/conversationRecovery.test.ts | 79 ++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/utils/conversationRecovery.test.ts b/src/utils/conversationRecovery.test.ts index cd9e7bd3..ec7694a8 100644 --- a/src/utils/conversationRecovery.test.ts +++ b/src/utils/conversationRecovery.test.ts @@ -4,6 +4,7 @@ import { tmpdir } from 'node:os' import { join } from 'node:path' import { + deserializeMessagesWithInterruptDetection, loadConversationForResume, ResumeTranscriptTooLargeError, } from './conversationRecovery.ts' @@ -46,6 +47,12 @@ async function writeJsonl(entry: unknown): Promise { afterEach(async () => { process.env.CLAUDE_CODE_SIMPLE = originalSimple + delete process.env.CLAUDE_CODE_USE_OPENAI + delete process.env.CLAUDE_CODE_USE_GEMINI + delete process.env.CLAUDE_CODE_USE_GITHUB + delete process.env.CLAUDE_CODE_USE_BEDROCK + delete process.env.CLAUDE_CODE_USE_VERTEX + delete process.env.CLAUDE_CODE_USE_FOUNDRY await Promise.all(tempDirs.splice(0).map(dir => rm(dir, { recursive: true, force: true }))) }) @@ -77,3 +84,75 @@ test('loadConversationForResume rejects oversized reconstructed transcripts', as ) }) +test('deserializeMessagesWithInterruptDetection strips thinking blocks only for OpenAI-compatible providers', () => { + const serializedMessages = [ + user(id(10), 'hello'), + { + type: 'assistant', + uuid: id(11), + parentUuid: id(10), + timestamp: ts, + cwd: '/tmp', + sessionId, + version: 'test', + message: { + role: 'assistant', + content: [ + { type: 'thinking', thinking: 'secret reasoning' }, + { type: 'text', text: 'visible reply' }, + ], + }, + }, + { + type: 'assistant', + uuid: id(12), + parentUuid: id(11), + timestamp: ts, + cwd: '/tmp', + sessionId, + version: 'test', + message: { + role: 'assistant', + content: [{ type: 'thinking', thinking: 'only hidden reasoning' }], + }, + }, + user(id(13), 'follow up'), + ] + + process.env.CLAUDE_CODE_USE_OPENAI = '1' + const thirdParty = deserializeMessagesWithInterruptDetection(serializedMessages as never[]) + const thirdPartyAssistantMessages = thirdParty.messages.filter( + message => message.type === 'assistant', + ) + + expect(thirdPartyAssistantMessages).toHaveLength(2) + expect(thirdPartyAssistantMessages[0]?.message?.content).toEqual([ + { type: 'text', text: 'visible reply' }, + ]) + expect( + JSON.stringify(thirdPartyAssistantMessages.map(message => message.message?.content)), + ).not.toContain('secret reasoning') + expect( + JSON.stringify(thirdPartyAssistantMessages.map(message => message.message?.content)), + ).not.toContain('only hidden reasoning') + + delete process.env.CLAUDE_CODE_USE_OPENAI + process.env.CLAUDE_CODE_USE_BEDROCK = '1' + const anthropicCompatible = deserializeMessagesWithInterruptDetection(serializedMessages as never[]) + const anthropicAssistantMessages = anthropicCompatible.messages.filter( + message => message.type === 'assistant', + ) + + expect(anthropicAssistantMessages).toHaveLength(2) + expect(anthropicAssistantMessages[0]?.message?.content).toEqual([ + { type: 'thinking', thinking: 'secret reasoning' }, + { type: 'text', text: 'visible reply' }, + ]) + expect( + JSON.stringify(anthropicAssistantMessages.map(message => message.message?.content)), + ).toContain('secret reasoning') + expect( + JSON.stringify(anthropicAssistantMessages.map(message => message.message?.content)), + ).not.toContain('only hidden reasoning') +}) +