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()
})
it('should NOT stop timer when isResponding is undefined (outside ChatContextProvider)', () => {
// Render without ChatContextProvider
it('should stop timer when isResponding is undefined (historical conversation outside active response)', () => {
// Render without ChatContextProvider — simulates historical conversation
render(
<ThinkBlock data-think={true}>
<p>Content without ENDTHINKFLAG</p>
</ThinkBlock>,
)
// Initial state should show "Thinking..."
expect(screen.getByText(/Thinking\.\.\./)).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()
// Timer should be stopped immediately — isResponding undefined means not in active response
expect(screen.getByText(/Thought/)).toBeInTheDocument()
})
})

View File

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