feat: 对话标题
This commit is contained in:
@@ -28,6 +28,9 @@
|
||||
import type { AgentParamsType } from '@/api/agent'
|
||||
import { useUserInfoStore, useProjectStore, useAgentStore } from '@/stores'
|
||||
import MyEvent from '@/utils/myEvent'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const userStore = useUserInfoStore()
|
||||
const agentStore = useAgentStore()
|
||||
@@ -267,6 +270,7 @@
|
||||
hasReportEvent = true
|
||||
// contentBody += `<slot slot-name="card" title="Report" content="Report"></slot>`
|
||||
hasReportStarted = true
|
||||
ElMessage.success(t('agent.generatingReport'))
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -337,6 +341,7 @@
|
||||
}
|
||||
if (jsonData.title) {
|
||||
emits('setTitle', jsonData.title)
|
||||
MyEvent.emit('newTitle', jsonData.title)
|
||||
}
|
||||
|
||||
if (hasSketch) {
|
||||
@@ -460,7 +465,13 @@
|
||||
}
|
||||
|
||||
// 处理对话列表,将连续的 assistant 消息合并为一条
|
||||
const processDialogue = (dialogue, startIndex, existingImgList, sessionId) => {
|
||||
const processDialogue = (
|
||||
dialogue,
|
||||
startIndex,
|
||||
existingImgList,
|
||||
sessionId,
|
||||
firstReportIndex = -1
|
||||
) => {
|
||||
if (!dialogue || dialogue.length === 0) return []
|
||||
|
||||
const result = []
|
||||
@@ -495,6 +506,11 @@
|
||||
j++
|
||||
}
|
||||
|
||||
// 如果 firstReportIndex 在当前合并范围内,则把 slot 追加到末尾
|
||||
if (firstReportIndex >= i && firstReportIndex < j) {
|
||||
combinedContent += `<slot slot-name="card" title="Report" content="Report"></slot>`
|
||||
}
|
||||
|
||||
result.push({
|
||||
...item,
|
||||
content: combinedContent,
|
||||
@@ -525,13 +541,12 @@
|
||||
const processSession = (session, imgList, ancestorsList, idCounterRef) => {
|
||||
if (!session) return
|
||||
|
||||
// 1. 在 dialogue 第一个 report 有值的项的 content 中插入报告卡片
|
||||
// 1. 找到第一个 report 项的索引,供 processDialogue 使用
|
||||
let firstReportIndex = -1
|
||||
if (session.dialogue) {
|
||||
for (let i = 0; i < session.dialogue.length; i++) {
|
||||
if (session.dialogue[i].report) {
|
||||
session.dialogue[i].content =
|
||||
`<slot slot-name="card" title="123" content="123">123</slot>` +
|
||||
(session.dialogue[i].content || '')
|
||||
firstReportIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -554,10 +569,11 @@
|
||||
}
|
||||
|
||||
// 4. 处理 dialogue
|
||||
const list = processDialogue(session.dialogue, 0, imgList, session.id)
|
||||
const list = processDialogue(session.dialogue, 0, imgList, session.id, firstReportIndex)
|
||||
list.forEach((el) => {
|
||||
el.id = idCounterRef.value++
|
||||
})
|
||||
|
||||
ancestorsList.push(...list)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:class="{ 'is-user': content.isUser, 'is-loading': content.loading }"
|
||||
>
|
||||
<div class="thumb">
|
||||
<img :src="content.isUser ? userThumb : agentThumb" class="thumb-icon" />
|
||||
<img :src="content.isUser ? userAvatar : agentThumb" class="thumb-icon" />
|
||||
</div>
|
||||
<div class="message-context" v-show="!content.loading">
|
||||
<div class="img-list flex" v-if="imageList.length > 0">
|
||||
@@ -120,6 +120,9 @@
|
||||
import type { CustomAttrs } from '@crazydos/vue-markdown'
|
||||
import rehypeRaw from 'rehype-raw'
|
||||
import MyEvent from '@/utils/myEvent'
|
||||
import { useUserInfoStore } from '@/stores'
|
||||
|
||||
const userStore = useUserInfoStore()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -128,16 +131,12 @@
|
||||
isLast: Boolean
|
||||
}>()
|
||||
|
||||
// watch(
|
||||
// () => props,
|
||||
// (newVal) => {
|
||||
// console.log('newVal-----', newVal)
|
||||
// },
|
||||
// { immediate: true }
|
||||
// )
|
||||
|
||||
const emit = defineEmits(['regenerate'])
|
||||
|
||||
const userAvatar = computed(() => {
|
||||
return userStore.state.userInfo?.avatar || userThumb
|
||||
})
|
||||
|
||||
const imageList = computed(() => {
|
||||
const { imageUrls, role } = props.content
|
||||
const list = []
|
||||
@@ -340,6 +339,7 @@
|
||||
.img-list {
|
||||
column-gap: 1rem;
|
||||
margin-bottom: 1.4rem;
|
||||
justify-content: flex-end;
|
||||
.img-item {
|
||||
width: 6.8rem;
|
||||
height: 6.8rem;
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, nextTick } from 'vue'
|
||||
import { computed, ref, nextTick, onMounted, onUnmounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { getProjectList, updateProject, deleteProject } from '@/api/agent'
|
||||
@@ -93,7 +93,8 @@
|
||||
const { t: $t } = useI18n()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
import { useGlobalStore } from '@/stores'
|
||||
import { useGlobalStore, useProjectStore } from '@/stores'
|
||||
const projectStore = useProjectStore()
|
||||
const id = computed(() => route.params.id)
|
||||
const globalStore = useGlobalStore()
|
||||
const isCollapse = computed(() => globalStore.state.homeLeftNavCollapse)
|
||||
@@ -198,8 +199,22 @@
|
||||
}
|
||||
MyEvent.add('updateProjectList', GetProjectList)
|
||||
GetProjectList()
|
||||
|
||||
const replaceTitle = (title: string) => {
|
||||
list.value.forEach((item: any) => {
|
||||
if (String(item.id) === String(projectStore.state.id)) {
|
||||
item.name = title
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
MyEvent.add('newTitle', replaceTitle)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
MyEvent.remove('newTitle', replaceTitle)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
.left-nav {
|
||||
width: var(--left-nav-collapse-width, 30rem);
|
||||
|
||||
Reference in New Issue
Block a user