import { describe, expect, it } from 'vitest' import { hasReasoningTag, splitReasoning } from '../lib/reasoning.js' import { cleanThinkingText } from '../lib/text.js' describe('splitReasoning', () => { it('extracts and strips it from text', () => { const { reasoning, text } = splitReasoning('plotting\n\nhere is the answer') expect(reasoning).toBe('plotting') expect(text).toBe('here is the answer') }) it('handles multiple tag shapes', () => { const input = 'a b c body' const { reasoning, text } = splitReasoning(input) expect(reasoning).toContain('a') expect(reasoning).toContain('b') expect(reasoning).toContain('c') expect(text).toBe('body') }) it('treats unclosed trailing … as reasoning', () => { const { reasoning, text } = splitReasoning('answer start still deciding') expect(reasoning).toBe('still deciding') expect(text).toBe('answer start') }) it('returns empty reasoning and untouched text when no tags present', () => { const { reasoning, text } = splitReasoning('plain body with no tags') expect(reasoning).toBe('') expect(text).toBe('plain body with no tags') }) it('preserves text when reasoning block is empty', () => { const { reasoning, text } = splitReasoning('only body') expect(reasoning).toBe('') expect(text).toBe('only body') }) it('detects presence of any supported tag', () => { expect(hasReasoningTag('pre x post')).toBe(true) expect(hasReasoningTag('pre x')).toBe(true) expect(hasReasoningTag('x')).toBe(true) expect(hasReasoningTag('no tags at all')).toBe(false) }) }) describe('cleanThinkingText', () => { it('removes face/status ticker fragments while preserving real reasoning', () => { expect( cleanThinkingText( '(¬_¬) synthesizing...**Resolving comments on GitHub**\n( ͡° ͜ʖ ͡°) musing...\nActual step\n٩(๑❛ᴗ❛๑)۶ contemplating...next step' ) ).toBe('**Resolving comments on GitHub**\nActual step\nnext step') }) })