This commit is contained in:
aaron 2025-05-11 18:14:43 +08:00
parent eb455551c2
commit 19be26fa9e
2 changed files with 45 additions and 60 deletions

View File

@ -5,7 +5,7 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
image: tradus-web:1.5 image: tradus-web:1.6
container_name: tradus-web container_name: tradus-web
ports: ports:
- '6000:80' - '6000:80'

View File

@ -166,24 +166,6 @@ watch(selectedAgent, (newAgent) => {
} }
}) })
// agentID
const getConversationId = (agentId: string) => {
const key = `conversation_${agentId}`
return localStorage.getItem(key)
}
// agentID
const saveConversationId = (agentId: string, conversationId: string) => {
const key = `conversation_${agentId}`
localStorage.setItem(key, conversationId)
}
// agentID
const clearConversationId = (agentId: string) => {
const key = `conversation_${agentId}`
localStorage.removeItem(key)
}
const showConfirmDialog = ref(false) const showConfirmDialog = ref(false)
const confirmDialogTitle = ref('') const confirmDialogTitle = ref('')
const confirmDialogMessage = ref('') const confirmDialogMessage = ref('')
@ -201,13 +183,11 @@ const selectAgent = (agent: Agent) => {
if (!selectedAgent.value || agent.id !== selectedAgent.value.id) { if (!selectedAgent.value || agent.id !== selectedAgent.value.id) {
// Agent // Agent
selectedAgent.value = agent selectedAgent.value = agent
clearConversationId(agent.id)
chatHistory.value = [] chatHistory.value = []
addInitialGreeting(agent).catch(console.error) addInitialGreeting(agent).catch(console.error)
} else { } else {
// Agent // Agent
showConfirm('重新开始对话', '是否重新开启新会话?', () => { showConfirm('重新开始对话', '是否重新开启新会话?', () => {
clearConversationId(agent.id)
chatHistory.value = [] chatHistory.value = []
addInitialGreeting(agent).catch(console.error) addInitialGreeting(agent).catch(console.error)
showConfirmDialog.value = false showConfirmDialog.value = false
@ -257,9 +237,6 @@ const sendMessage = async () => {
headers['Authorization'] = userStore.authHeader headers['Authorization'] = userStore.authHeader
} }
// agentID
const conversationId = selectedAgent.value ? getConversationId(selectedAgent.value.id) : null
// //
const response = await fetch(`${apiBaseUrl}/agent/chat`, { const response = await fetch(`${apiBaseUrl}/agent/chat`, {
method: 'POST', method: 'POST',
@ -267,12 +244,13 @@ const sendMessage = async () => {
body: JSON.stringify({ body: JSON.stringify({
user_prompt: currentInput, user_prompt: currentInput,
agent_id: selectedAgent.value.id, agent_id: selectedAgent.value.id,
conversation_id: conversationId,
}), }),
}) })
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`) const errorText = await response.text()
console.error('API响应错误:', response.status, errorText)
throw new Error(`服务器响应错误: ${response.status} - ${errorText || '未知错误'}`)
} }
const reader = response.body?.getReader() const reader = response.body?.getReader()
@ -281,6 +259,7 @@ const sendMessage = async () => {
} }
const decoder = new TextDecoder() const decoder = new TextDecoder()
let buffer = '' // JSON
// //
while (true) { while (true) {
@ -288,18 +267,20 @@ const sendMessage = async () => {
if (done) break if (done) break
const chunk = decoder.decode(value, { stream: true }) const chunk = decoder.decode(value, { stream: true })
const lines = chunk.split('\n') buffer += chunk
//
const lines = buffer.split('\n')
//
buffer = lines.pop() || ''
for (const line of lines) { for (const line of lines) {
if (!line.trim() || !line.startsWith('data: ')) continue if (!line.trim() || !line.startsWith('data: ')) continue
try { try {
const data = JSON.parse(line.slice(6)) const jsonStr = line.slice(6) // "data: "
console.log('收到的JSON数据:', jsonStr) //
// conversation_id const data = JSON.parse(jsonStr)
if (data.conversation_id && selectedAgent.value) {
saveConversationId(selectedAgent.value.id, data.conversation_id)
}
switch (data.event) { switch (data.event) {
case 'agent_message': case 'agent_message':
@ -312,7 +293,7 @@ const sendMessage = async () => {
case 'agent_thought': case 'agent_thought':
if (data.tool) { if (data.tool) {
const thoughtText = `Agent 正在调用 ${data.tool} 工具` const thoughtText = `Agent 正在调用 ${data.tool} 工具`
chatHistory.value[tempMessageIndex].content = currentResponseText.value chatHistory.value[tempMessageIndex].content = currentResponseText.value
? `${thoughtText}\n\n${currentResponseText.value}` ? `${thoughtText}\n\n${currentResponseText.value}`
: thoughtText : thoughtText
@ -320,35 +301,36 @@ const sendMessage = async () => {
} }
break break
case 'message_file': case 'error':
if (data.type === 'image') { const errorMessage = data.error || '未知错误'
// chatHistory.value[tempMessageIndex].content =
const lastIndex = chatHistory.value.length - 1 `抱歉,处理您的请求时出错了:${errorMessage}`
if (chatHistory.value[lastIndex].role === 'assistant') { isLoading.value = false
chatHistory.value[lastIndex].files.push({ await scrollToBottom()
type: 'image',
url: data.url,
})
}
}
break break
case 'message_end': case 'message_end':
break if (currentResponseText.value.trim()) {
chatHistory.value[tempMessageIndex].content = currentResponseText.value
case 'tts_message': }
//
break break
} }
} catch (e) { } catch (e) {
console.error('解析响应数据出错:', e) console.error('解析JSON数据出错:', e, '原始数据:', line)
if (line.includes('<!DOCTYPE html>') || line.includes('<html>')) {
chatHistory.value[tempMessageIndex].content =
'抱歉,服务器返回了错误的响应格式,请稍后再试。'
} else {
chatHistory.value[tempMessageIndex].content = '抱歉,解析响应数据时出错了,请稍后再试。'
}
await scrollToBottom()
} }
} }
} }
} catch (error) { } catch (error) {
console.error('调用API出错:', error) console.error('调用API出错:', error)
// const errorMessage = error instanceof Error ? error.message : '未知错误'
chatHistory.value[tempMessageIndex].content = '抱歉,请求出错了。请稍后再试。' chatHistory.value[tempMessageIndex].content = `抱歉,请求出错了:${errorMessage}`
await scrollToBottom() await scrollToBottom()
} finally { } finally {
isLoading.value = false isLoading.value = false
@ -420,7 +402,7 @@ const getInitial = (nickname: string) => {
: 'ai-message', : 'ai-message',
]" ]"
> >
<div v-if="message.role === 'assistant'" class="avatar"> <div v-if="message.role === 'assistant'" class="avatar ai-avatar">
<svg <svg
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
@ -725,17 +707,20 @@ const getInitial = (nickname: string) => {
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
} }
.user-message .avatar { .user-avatar {
order: 1;
background-color: var(--color-accent); background-color: var(--color-accent);
color: white;
font-size: 1.1rem;
font-weight: 500;
border: none; border: none;
} }
.user-message .avatar svg { .ai-avatar {
color: white; background-color: var(--color-bg-secondary);
border: 1px solid var(--color-border);
} }
.avatar svg { .ai-avatar svg {
width: 24px; width: 24px;
height: 24px; height: 24px;
color: var(--color-accent); color: var(--color-accent);
@ -783,14 +768,14 @@ const getInitial = (nickname: string) => {
.user-message .message-content { .user-message .message-content {
background-color: var(--color-accent); background-color: var(--color-accent);
color: white; color: white;
border-radius: 1rem 0 1rem 1rem; border-radius: 0 1rem 1rem 1rem;
padding: 1.25rem; padding: 1.25rem;
} }
.ai-message .message-content { .ai-message .message-content {
background-color: var(--color-bg-secondary); background-color: var(--color-bg-secondary);
color: var(--color-text-primary); color: var(--color-text-primary);
border-radius: 0 1rem 1rem 1rem; border-radius: 1rem 0 1rem 1rem;
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
padding: 1.25rem; padding: 1.25rem;
margin-top: 0.5rem; margin-top: 0.5rem;