update
This commit is contained in:
parent
eb455551c2
commit
19be26fa9e
@ -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'
|
||||||
|
|||||||
@ -166,24 +166,6 @@ watch(selectedAgent, (newAgent) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取当前agent的会话ID
|
|
||||||
const getConversationId = (agentId: string) => {
|
|
||||||
const key = `conversation_${agentId}`
|
|
||||||
return localStorage.getItem(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存当前agent的会话ID
|
|
||||||
const saveConversationId = (agentId: string, conversationId: string) => {
|
|
||||||
const key = `conversation_${agentId}`
|
|
||||||
localStorage.setItem(key, conversationId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清除当前agent的会话ID
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前agent的会话ID
|
|
||||||
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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user