feat: 拼接多条assistant消息

This commit is contained in:
2026-03-04 14:02:11 +08:00
parent a55cfd5e0c
commit 8f07041639
3 changed files with 78 additions and 32 deletions

View File

@@ -221,7 +221,8 @@
}
buffer += decoder.decode(value, { stream: true })
console.log('收到chunk',new Date().getTime());
// 优先按空行拆分事件块SSE标准
let events = buffer.split(/\n\n/)
buffer = events.pop() // 保留不完整块
@@ -261,7 +262,7 @@
try {
const jsonData = JSON.parse(jsonText)
console.log('jsonData', jsonData)
// console.log('jsonData', jsonData)
// 赋值 project_id 和 version_id
// if (jsonData.project_id) params.projectID = jsonData.project_id
@@ -361,6 +362,67 @@
)
}
// 处理对话列表,将连续的 assistant 消息合并为一条
const processDialogue = (dialogue, startIndex, existingImgList) => {
if (!dialogue || dialogue.length === 0) return []
const result = []
let i = startIndex
while (i < dialogue.length) {
const item = dialogue[i]
if (item.image_url) {
existingImgList.push(item.image_url)
}
if (item.role === 'user') {
// user 角色直接添加
result.push({
...item,
text: item.content,
isUser: true,
id: result.length + 1
})
i++
} else if (item.role === 'assistant') {
// assistant 角色,拼接直到下一个 user
let combinedContent = item.content || ''
// 继续往后找连续的 assistant 消息
let j = i + 1
while (j < dialogue.length && dialogue[j].role === 'assistant') {
if (dialogue[j].image_url) {
existingImgList.push(dialogue[j].image_url)
}
combinedContent += dialogue[j].content || ''
j++
}
result.push({
...item,
content: combinedContent,
text: combinedContent,
isUser: false,
id: result.length + 1
})
i = j
} else {
// 其他角色直接添加
result.push({
...item,
text: item.content,
isUser: item.role === 'user',
id: result.length + 1
})
i++
}
}
return result
}
const setChatInfo = (info) => {
const initialData = agentStore.getInitialProjectData
if (isGenerating.value || initialData) return
@@ -389,35 +451,22 @@
const imgList = []
const ancestorsList = []
let ancestorsIdCounter = 1
if (ancestors) {
ancestors.forEach((item) => {
const list =
item.dialogue?.map((el, index) => {
if (el.image_url) {
imgList.push(el.image_url)
}
return {
...el,
text: el.content,
isUser: el.role === 'user',
id: index + 1
}
}) || []
const list = processDialogue(item.dialogue, 0, imgList)
// 重新设置 id
list.forEach((el) => {
el.id = ancestorsIdCounter++
})
ancestorsList.push(...list)
})
}
const currentList =
current?.dialogue?.map((item, index) => {
if (item.image_url) {
imgList.push(item.image_url)
}
return {
...item,
text: item.content,
isUser: item.role === 'user',
id: index + 1 + ancestorsList.length
}
}) || []
const currentList = processDialogue(current?.dialogue, 0, imgList)
// 重新设置 id
currentList.forEach((el, index) => {
el.id = index + 1 + ancestorsList.length
})
// 延迟设置新数据,确保 UI 有时间响应清空操作
nextTick(() => {

View File

@@ -7,10 +7,7 @@
<div class="thumb">
<img :src="content.isUser ? userThumb : agentThumb" class="thumb-icon" />
</div>
<div
class="message-context"
v-show="!content.loading && !content.thinking && !content.streaming"
>
<div class="message-context" v-show="!content.loading">
<div class="img-list flex" v-if="imageList.length > 0">
<img
v-for="(item, index) in imageList"

View File

@@ -517,8 +517,8 @@
const settingPopupVisible = ref(false)
const settingOptions = ref([
{ label: 'Input.settingOptions.creativity', value: 50 },
{ label: 'Input.settingOptions.diversity', value: 75 },
{ label: 'Input.settingOptions.relevance', value: 60 }
{ label: 'Input.settingOptions.diversity', value: 50 },
{ label: 'Input.settingOptions.relevance', value: 50 }
])
const openStylePopup = () => {