fix: glitch UI thinking or duplicate content when multiple think after tools call (#5217)
* fix: update id streaming content think * fix: glitch UI or duplicate content when multiple thinking
This commit is contained in:
parent
44b5310a6a
commit
1bbac32d88
@ -1,20 +1,53 @@
|
||||
import { useAppState } from '@/hooks/useAppState'
|
||||
import { ThreadContent } from './ThreadContent'
|
||||
import { memo } from 'react'
|
||||
import { memo, useMemo } from 'react'
|
||||
import { useMessages } from '@/hooks/useMessages'
|
||||
|
||||
type Props = {
|
||||
threadId: string
|
||||
}
|
||||
|
||||
// Helper to extract <think>...</think> segment
|
||||
function extractReasoningSegment(text: string) {
|
||||
if (!text) return ''
|
||||
const match = text.match(/<think>([\s\S]*?)<\/think>/)
|
||||
if (match) return match[0].trim()
|
||||
// If only opening <think> and no closing, take everything after <think>
|
||||
const openIdx = text.indexOf('<think>')
|
||||
if (openIdx !== -1) return text.slice(openIdx).trim()
|
||||
return ''
|
||||
}
|
||||
|
||||
// Use memo with no dependencies to allow re-renders when props change
|
||||
// Avoid duplicate reasoning segments after tool calls
|
||||
export const StreamingContent = memo(({ threadId }: Props) => {
|
||||
const { streamingContent } = useAppState()
|
||||
const { getMessages } = useMessages()
|
||||
const messages = getMessages(threadId)
|
||||
|
||||
const streamingReasoning = useMemo(() => {
|
||||
const text =
|
||||
streamingContent?.content?.find((e) => e.type === 'text')?.text?.value ||
|
||||
''
|
||||
return extractReasoningSegment(text)
|
||||
}, [streamingContent])
|
||||
|
||||
const lastAssistant = useMemo(() => {
|
||||
return [...messages].reverse().find((m) => m.role === 'assistant')
|
||||
}, [messages])
|
||||
const lastAssistantReasoning = useMemo(() => {
|
||||
if (!lastAssistant) return ''
|
||||
const text =
|
||||
lastAssistant.content?.find((e) => e.type === 'text')?.text?.value || ''
|
||||
return extractReasoningSegment(text)
|
||||
}, [lastAssistant])
|
||||
|
||||
if (!streamingContent || streamingContent.thread_id !== threadId) return null
|
||||
|
||||
if (streamingReasoning && streamingReasoning === lastAssistantReasoning) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Pass a new object to ThreadContent to avoid reference issues
|
||||
// The streaming content is always the last message
|
||||
return (
|
||||
|
||||
@ -302,7 +302,7 @@ export const ThreadContent = memo(
|
||||
<ThinkingBlock
|
||||
id={
|
||||
item.isLastMessage
|
||||
? `${item.thread_id}-last`
|
||||
? `${item.thread_id}-last-${reasoningSegment.slice(0, 50).replace(/\s/g, '').slice(-10)}`
|
||||
: `${item.thread_id}-${item.index ?? item.id}`
|
||||
}
|
||||
text={reasoningSegment}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user