fix: stop think block timer in historical conversations (#33083)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lubrsy
2026-03-20 11:03:35 +08:00
committed by GitHub
parent 8c9831177a
commit 40eacf8f32
2 changed files with 9 additions and 18 deletions

View File

@ -163,25 +163,16 @@ describe('ThinkBlock', () => {
expect(screen.getByText(/Thought/)).toBeInTheDocument() expect(screen.getByText(/Thought/)).toBeInTheDocument()
}) })
it('should NOT stop timer when isResponding is undefined (outside ChatContextProvider)', () => { it('should stop timer when isResponding is undefined (historical conversation outside active response)', () => {
// Render without ChatContextProvider // Render without ChatContextProvider — simulates historical conversation
render( render(
<ThinkBlock data-think={true}> <ThinkBlock data-think={true}>
<p>Content without ENDTHINKFLAG</p> <p>Content without ENDTHINKFLAG</p>
</ThinkBlock>, </ThinkBlock>,
) )
// Initial state should show "Thinking..." // Timer should be stopped immediately — isResponding undefined means not in active response
expect(screen.getByText(/Thinking\.\.\./)).toBeInTheDocument() expect(screen.getByText(/Thought/)).toBeInTheDocument()
// Advance timer
act(() => {
vi.advanceTimersByTime(2000)
})
// Timer should still be running (showing "Thinking..." not "Thought")
expect(screen.getByText(/Thinking\.\.\./)).toBeInTheDocument()
expect(screen.getByText(/\(2\.0s\)/)).toBeInTheDocument()
}) })
}) })

View File

@ -39,9 +39,10 @@ const removeEndThink = (children: any): any => {
const useThinkTimer = (children: any) => { const useThinkTimer = (children: any) => {
const { isResponding } = useChatContext() const { isResponding } = useChatContext()
const endThinkDetected = hasEndThink(children)
const [startTime] = useState(() => Date.now()) const [startTime] = useState(() => Date.now())
const [elapsedTime, setElapsedTime] = useState(0) const [elapsedTime, setElapsedTime] = useState(0)
const [isComplete, setIsComplete] = useState(false) const [isComplete, setIsComplete] = useState(() => endThinkDetected)
const timerRef = useRef<NodeJS.Timeout | null>(null) const timerRef = useRef<NodeJS.Timeout | null>(null)
useEffect(() => { useEffect(() => {
@ -61,11 +62,10 @@ const useThinkTimer = (children: any) => {
useEffect(() => { useEffect(() => {
// Stop timer when: // Stop timer when:
// 1. Content has [ENDTHINKFLAG] marker (normal completion) // 1. Content has [ENDTHINKFLAG] marker (normal completion)
// 2. isResponding is explicitly false (user clicked stop button) // 2. isResponding is not true (false = user clicked stop, undefined = historical conversation)
// Note: Don't stop when isResponding is undefined (component used outside ChatContextProvider) if (endThinkDetected || !isResponding)
if (hasEndThink(children) || isResponding === false)
setIsComplete(true) setIsComplete(true)
}, [children, isResponding]) }, [endThinkDetected, isResponding])
return { elapsedTime, isComplete } return { elapsedTime, isComplete }
} }