本地 RAG 知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

60 lines
2.0 KiB

/**
* 将项目内部 ChatMessage 模型适配为 @tdesign-vue-next/chat 的 ChatItemMeta 数据格式
*
* ChatList 内部用 ChatMessage 组件渲染每条消息,读取字段:role / name / datetime / avatar / content。
* 注意:ChatList 源码会把任何 truthy 的 status 都重写成 "pending" 导致显示骨架,因此我们不传 status,
* 由 ChatPanel.vue 的 #content slot 完全接管内容渲染(包括流式/错误态)。
*/
import type { TdChatItemMeta, AIMessageContent, UserMessageContent } from '@tdesign-vue-next/chat'
/** 附件信息(图片或文件) */
export interface Attachment {
name: string
url: string
type: 'image' | 'file'
mimeType?: string
size?: number
}
/** 项目内部消息模型(与 ChatPanel.vue 中 ChatMessage 保持一致) */
export interface ChatMessage {
id: string
role: 'user' | 'assistant'
content: string
streaming: boolean
time: string
sources?: any[]
toolCalls?: any[]
error?: boolean
feedback?: string | null
attachments?: Attachment[]
}
/** 转换单条消息 */
export function toChatItemMeta(msg: ChatMessage): TdChatItemMeta {
const isUser = msg.role === 'user'
return {
role: isUser ? 'user' : 'assistant',
name: isUser ? '我' : 'Support Bot',
avatar: isUser ? '' : undefined,
datetime: msg.time,
content: isUser
? ([{ type: 'text', data: msg.content || '' }] as UserMessageContent[])
: ([{ type: 'markdown', data: msg.content || '' }] as AIMessageContent[]),
// 故意不传 status:ChatList 会把 truthy status 强制改为 pending,显示骨架屏
}
}
/** 批量转换 */
export function toChatData(messages: ChatMessage[]): TdChatItemMeta[] {
return messages.map(toChatItemMeta)
}
/** 根据消息索引判断是否为最后一条 assistant 消息 */
export function isLastAssistant(index: number, messages: ChatMessage[]): boolean {
for (let i = messages.length - 1; i >= 0; i--) {
if (messages[i].role === 'assistant') return i === index
}
return false
}