diff --git a/backend/apps/chat/curd/chat.py b/backend/apps/chat/curd/chat.py index 5ffbd940..2ca9ecb8 100644 --- a/backend/apps/chat/curd/chat.py +++ b/backend/apps/chat/curd/chat.py @@ -546,6 +546,8 @@ def save_recommend_question_answer(session: SessionDep, record_id: int, session.commit() record = get_chat_record_by_id(session, record_id) + record.recommended_question_answer = recommended_question_answer + record.recommended_question = recommended_question return record diff --git a/backend/apps/chat/task/llm.py b/backend/apps/chat/task/llm.py index ec5e9d1d..0f47af7f 100644 --- a/backend/apps/chat/task/llm.py +++ b/backend/apps/chat/task/llm.py @@ -1029,10 +1029,10 @@ class LLMService: for chunk in res: if chunk.get('recommended_question'): - yield orjson.dumps( + yield 'data:' + orjson.dumps( {'content': chunk.get('recommended_question'), 'type': 'recommended_question'}).decode() + '\n\n' else: - yield orjson.dumps( + yield 'data:' + orjson.dumps( {'content': chunk.get('content'), 'reasoning_content': chunk.get('reasoning_content'), 'type': 'recommended_question_result'}).decode() + '\n\n' diff --git a/frontend/src/views/chat/RecommendQuestion.vue b/frontend/src/views/chat/RecommendQuestion.vue index 15d97222..a192b0a4 100644 --- a/frontend/src/views/chat/RecommendQuestion.vue +++ b/frontend/src/views/chat/RecommendQuestion.vue @@ -63,7 +63,9 @@ async function getRecommendQuestions() { const controller: AbortController = new AbortController() const response = await chatApi.recommendQuestions(props.recordId, controller) const reader = response.body.getReader() - const decoder = new TextDecoder() + const decoder = new TextDecoder('utf-8') + + let tempResult = '' while (true) { if (stopFlag.value) { @@ -77,60 +79,56 @@ async function getRecommendQuestions() { break } - const chunk = decoder.decode(value) - - let _list = [chunk] - - const lines = chunk.trim().split('}\n\n{') - if (lines.length > 1) { - _list = [] - for (let line of lines) { - if (!line.trim().startsWith('{')) { - line = '{' + line.trim() - } - if (!line.trim().endsWith('}')) { - line = line.trim() + '}' - } - _list.push(line) - } + let chunk = decoder.decode(value, { stream: true }) + tempResult += chunk + const split = tempResult.match(/data:.*}\n\n/g) + if (split) { + chunk = split.join('') + tempResult = tempResult.replace(chunk, '') + } else { + continue } - for (const str of _list) { - let data - try { - data = JSON.parse(str) - } catch (err) { - console.error('JSON string:', str) - throw err - } + if (chunk && chunk.startsWith('data:{')) { + if (split) { + for (const str of split) { + let data + try { + data = JSON.parse(str.replace('data:{', '{')) + } catch (err) { + console.error('JSON string:', str) + throw err + } - if (data.code && data.code !== 200) { - ElMessage({ - message: data.msg, - type: 'error', - showClose: true, - }) - return - } + if (data.code && data.code !== 200) { + ElMessage({ + message: data.msg, + type: 'error', + showClose: true, + }) + return + } - switch (data.type) { - case 'recommended_question': - if ( - data.content && - data.content.length > 0 && - startsWith(data.content.trim(), '[') && - endsWith(data.content.trim(), ']') - ) { - if (_currentChat.value?.records) { - for (let record of _currentChat.value.records) { - if (record.id === props.recordId) { - record.recommended_question = data.content + switch (data.type) { + case 'recommended_question': + if ( + data.content && + data.content.length > 0 && + startsWith(data.content.trim(), '[') && + endsWith(data.content.trim(), ']') + ) { + if (_currentChat.value?.records) { + for (let record of _currentChat.value.records) { + if (record.id === props.recordId) { + record.recommended_question = data.content - await nextTick() + await nextTick() + } + } } } - } } + } } } }