Compare commits

...

2 Commits

Author SHA1 Message Date
wangyunfei a7edbcf865 伪流式 1 month ago
wangyunfei eb453493fc 伪流式输出 1 month ago

@ -110,21 +110,36 @@ export const callLocalChatAPI = async (prompt, onStreamData) => {
// 按行处理响应
const lines = responseText.split(/\r?\n/)
console.log('总行数:', lines.length)
for (const line of lines) {
for (let i = 0; i < lines.length; i++) {
const line = lines[i]
if (line.startsWith('event:')) {
currentEvent = line.substring(6).trim()
console.log(`${i}行 - 事件类型:`, currentEvent)
} else if (line.startsWith('data:')) {
const data = line.substring(5)
console.log(`${i}行 - 数据类型:${currentEvent}, 数据长度:${data.length}, 数据内容:${data.substring(0, 50)}...`)
if (currentEvent === 'thought') {
thoughtContent += data
} else if (currentEvent === 'message') {
// 累加所有 message 数据,而不是只处理第一个
messageContent += data
console.log(`messageContent 当前长度: ${messageContent.length}`)
}
}
}
// 调试:打印解析结果
console.log('解析结果:', {
thoughtLength: thoughtContent.length,
messageLength: messageContent.length,
thought: thoughtContent.substring(0, 100) + '...',
message: messageContent.substring(0, 100) + '...'
})
// 返回最终结果
console.log('API returning:3333', { thought: thoughtContent, message: messageContent }) // 调试信息

@ -47,6 +47,13 @@ function ChatConversation() {
const [typingMessage, setTypingMessage] = useState('')
const [isTyping, setIsTyping] = useState(false)
const [streamingContent, setStreamingContent] = useState('')
const [isStreaming, setIsStreaming] = useState(false)
const [currentStreamingMessageId, setCurrentStreamingMessageId] = useState(null)
// 流式输出状态 - 已移除
const messagesEndRef = useRef(null)
@ -127,6 +134,41 @@ function ChatConversation() {
typeNextWords()
}
// 模拟流式效果
const simulateStreamingEffect = (fullContent, messageId) => {
console.log('开始流式效果:', { fullContent: fullContent.substring(0, 100) + '...', messageId, length: fullContent.length })
setIsStreaming(true)
setStreamingContent('')
setCurrentStreamingMessageId(messageId)
let currentIndex = 0
const chunkSize = 3 // 每次显示3个字符
const delay = 50 // 50ms间隔可以调整速度
const streamNext = () => {
if (currentIndex < fullContent.length) {
const nextIndex = Math.min(currentIndex + chunkSize, fullContent.length)
const currentContent = fullContent.substring(0, nextIndex)
console.log('流式进度:', { currentIndex, nextIndex, currentContent: currentContent.substring(0, 50) + '...' })
setStreamingContent(currentContent)
conversationStore.updateMessage(messageId, currentContent)
currentIndex = nextIndex
setTimeout(streamNext, delay)
} else {
// 流式效果完成
console.log('流式效果完成')
setIsStreaming(false)
setStreamingContent('')
setCurrentStreamingMessageId(null)
}
}
streamNext()
}
// 创建新对话
const createNewConversation = () => {
@ -183,7 +225,7 @@ function ChatConversation() {
setLoading(true)
try {
// 调用本地后端接口(非流式版本)
// 调用本地后端接口
const result = await callLocalChatAPI(messageText)
console.log('API result:', result)
@ -200,9 +242,12 @@ function ChatConversation() {
console.log('Final content:', finalContent)
if (finalContent.trim()) {
// 暂时直接添加消息,不使用打字机效果
console.log('Adding message directly:', finalContent)
conversationStore.addMessage('assistant', finalContent)
// 先添加一个空的助手消息
const assistantMessageId = conversationStore.addMessage('assistant', '')
setCurrentStreamingMessageId(assistantMessageId)
// 开始模拟流式效果
simulateStreamingEffect(finalContent, assistantMessageId)
} else {
console.log('No content, adding fallback message')
conversationStore.addMessage('assistant', '抱歉,我无法生成回复内容。')
@ -270,14 +315,22 @@ function ChatConversation() {
// 渲染单条消息 ==================================
const renderMessage = (msg, index) => {
const isUser = msg.role === 'user'
const displayContent = msg.content || ''
// 如果是当前正在流式输出的消息,显示流式内容
const isCurrentStreaming = isStreaming &&
currentStreamingMessageId === msg.id &&
msg.role === 'assistant'
const displayContent = isCurrentStreaming ? streamingContent : (msg.content || '')
// 调试信息
if (msg.role === 'assistant') {
console.log('Rendering assistant message:', {
index,
content: msg.content,
displayContent
displayContent,
isCurrentStreaming,
streamingContent
})
}
@ -346,11 +399,67 @@ function ChatConversation() {
{/* 回答框 */}
<div className='ds-message-content'>
{displayContent ? (
<ReactMarkdown
remarkPlugins={[remarkGfm]}
>
{displayContent}
</ReactMarkdown>
<div>
{deepThinkingEnabled && displayContent.includes('\n\n') ? (
// 当开启深度思考且有思考内容时,分别渲染
(() => {
const parts = displayContent.split('\n\n')
const thought = parts[0]
const message = parts.slice(1).join('\n\n')
return (
<>
{/* 思考过程 */}
<div
style={{
fontSize: '14px',
color: '#666',
padding: '5px',
backgroundColor: '#f5f5f5',
borderRadius: '4px',
marginBottom: '10px',
// fontStyle: 'italic',
borderLeft: '3px solid #d9d9d9'
}}
>
<strong>思考过程</strong>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
p: ({children}) => <span style={{fontSize: '14px'}}>{children}</span>,
strong: ({children}) => <strong style={{fontSize: '14px'}}>{children}</strong>,
em: ({children}) => <em style={{fontSize: '14px'}}>{children}</em>,
code: ({children}) => <code style={{fontSize: '14px'}}>{children}</code>,
pre: ({children}) => <pre style={{fontSize: '14px'}}>{children}</pre>
}}
>
{thought}
</ReactMarkdown>
</div>
{/* 正式回答 */}
{message && (
<div>
{/* <strong style={{fontSize: '12px', color: '#333', marginBottom: '4px', display: 'block'}}>回答:</strong> */}
<ReactMarkdown
remarkPlugins={[remarkGfm]}
>
{message}
</ReactMarkdown>
</div>
)}
</>
)
})()
) : (
// 普通渲染
<ReactMarkdown
remarkPlugins={[remarkGfm]}
>
{displayContent}
</ReactMarkdown>
)}
</div>
) : (
<div style={{ color: '#999', fontStyle: 'italic' }}>
暂无内容

@ -102,6 +102,7 @@ class PageConversationStore {
const currentConversation = this.getCurrentConversation()
if (currentConversation) {
const newMessage = {
id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
role,
content,
timestamp: new Date()
@ -118,6 +119,28 @@ class PageConversationStore {
this.saveToStorage()
this.notifySubscribers()
return newMessage.id
}
return null
}
// 更新指定消息的内容
updateMessage(messageId, newContent) {
console.log('updateMessage 调用:', { messageId, newContent: newContent.substring(0, 50) + '...', length: newContent.length })
const currentConversation = this.getCurrentConversation()
if (currentConversation) {
const message = currentConversation.messages.find(msg => msg.id === messageId)
if (message) {
console.log('找到消息,更新内容:', { oldContent: message.content.substring(0, 50) + '...', newContent: newContent.substring(0, 50) + '...' })
message.content = newContent
currentConversation.lastUpdate = new Date()
this.saveToStorage()
this.notifySubscribers()
} else {
console.log('未找到消息:', messageId)
}
} else {
console.log('未找到当前对话')
}
}

Loading…
Cancel
Save