feat(avatar): add private vision chat support

This commit is contained in:
stefanfeng
2026-08-31 15:10:50 +08:00
parent 094f8cd40f
commit 016bc22c05
22 changed files with 1616 additions and 59 deletions
+49 -7
View File
@@ -374,15 +374,35 @@ export const searchKnowledge = (avatarId: string, q: string, topK = 5) =>
export interface ChatMessage {
role: 'user' | 'assistant'
content: string
attachmentIds?: string[]
}
export interface ChatResponse {
answer: string
source: 'qa' | 'knowledge' | 'qwen'
source: 'qa' | 'knowledge' | 'vision' | 'qwen'
references?: Array<{ docId?: string; filename?: string; fileType?: string; snippet?: string; score?: number }>
}
export const sendAvatarChat = (avatarId: string, payload: { message: string; history?: ChatMessage[] }) =>
export interface ChatAttachment {
id: string
avatarId: string
filename: string
mimeType: string
fileSize: number
status: 'processing' | 'ready' | 'failed'
category: 'general_image' | 'document' | 'medical_document' | 'medical_image'
summary: string
warning: string
expiresAt: string
}
export interface ChatPayload {
message: string
attachmentIds?: string[]
history?: ChatMessage[]
}
export const sendAvatarChat = (avatarId: string, payload: ChatPayload) =>
request.post<ChatResponse>(`/avatar/${avatarId}/chat`, payload)
export interface PublicAvatar {
@@ -401,19 +421,41 @@ export const createAvatarShareLink = (avatarId: string) =>
export const getPublicAvatar = (shareToken: string) =>
request.get<PublicAvatar>(`/public/avatar/${shareToken}`)
export const sendPublicAvatarChat = (shareToken: string, payload: { message: string; history?: ChatMessage[] }) =>
export const sendPublicAvatarChat = (shareToken: string, payload: ChatPayload) =>
request.post<ChatResponse>(`/public/avatar/${shareToken}/chat`, payload)
const imageForm = (file: File) => {
const form = new FormData()
form.append('file', file)
return form
}
export const uploadAvatarChatImage = (avatarId: string, file: File) =>
request.post<ChatAttachment>(`/avatar/${avatarId}/chat/images`, imageForm(file), {
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 120000
})
export const uploadPublicAvatarChatImage = (shareToken: string, file: File) =>
request.post<ChatAttachment>(`/public/avatar/${shareToken}/chat/images`, imageForm(file), {
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 120000
})
type ChatStreamHandlers = {
onMeta: (meta: Pick<ChatResponse, 'source' | 'references'>) => void
onDelta: (content: string) => void
}
const streamChat = async (path: string, payload: { message: string; history?: ChatMessage[] }, handlers: ChatStreamHandlers) => {
const streamChat = async (path: string, payload: ChatPayload, handlers: ChatStreamHandlers) => {
const headers: Record<string, string> = { 'Content-Type': 'application/json', Accept: 'text/event-stream' }
if (_authToken) headers.Authorization = `Bearer ${_authToken}`
const response = await fetch(`${resolveBaseURL()}${path}`, { method: 'POST', headers, body: JSON.stringify(payload) })
if (!response.ok || !response.body) throw new Error(`对话请求失败(${response.status})`)
if (!response.ok) {
const errorBody = await response.json().catch(() => null)
throw new Error(errorBody?.detail || errorBody?.message || `对话请求失败(${response.status})`)
}
if (!response.body) throw new Error('对话响应为空,请稍后重试')
const reader = response.body.getReader()
const decoder = new TextDecoder()
@@ -436,10 +478,10 @@ const streamChat = async (path: string, payload: { message: string; history?: Ch
}
}
export const streamAvatarChat = (avatarId: string, payload: { message: string; history?: ChatMessage[] }, handlers: ChatStreamHandlers) =>
export const streamAvatarChat = (avatarId: string, payload: ChatPayload, handlers: ChatStreamHandlers) =>
streamChat(`/avatar/${avatarId}/chat/stream`, payload, handlers)
export const streamPublicAvatarChat = (shareToken: string, payload: { message: string; history?: ChatMessage[] }, handlers: ChatStreamHandlers) =>
export const streamPublicAvatarChat = (shareToken: string, payload: ChatPayload, handlers: ChatStreamHandlers) =>
streamChat(`/public/avatar/${shareToken}/chat/stream`, payload, handlers)
// ==================== 会会用户资料 API ====================