feat(chat): 增强对话中断处理,优化用户体验
- 在 chat_agent 函数中添加对客户端主动中断连接的处理,尝试保存已生成的部分内容 - 更新前端 AgentChatComponent.vue,新增发送或中断功能,确保用户可以中断对话生成并刷新消息历史 - 优化状态处理,确保中断状态下的消息历史刷新逻辑正常工作
This commit is contained in:
parent
b90a796172
commit
23f8fed679
@ -322,6 +322,26 @@ async def chat_agent(
|
|||||||
conv_mgr=conv_manager,
|
conv_mgr=conv_manager,
|
||||||
config_dict=langgraph_config,
|
config_dict=langgraph_config,
|
||||||
)
|
)
|
||||||
|
except (asyncio.CancelledError, ConnectionError) as e:
|
||||||
|
# 客户端主动中断连接,尝试保存已生成的部分内容
|
||||||
|
logger.info(f"Client disconnected for thread {thread_id}: {e}")
|
||||||
|
try:
|
||||||
|
if conversation:
|
||||||
|
langgraph_config = {"configurable": {"thread_id": thread_id, "user_id": user_id}}
|
||||||
|
await save_messages_from_langgraph_state(
|
||||||
|
agent_instance=agent,
|
||||||
|
conversation=conversation,
|
||||||
|
conv_mgr=conv_manager,
|
||||||
|
config_dict=langgraph_config,
|
||||||
|
)
|
||||||
|
except Exception as save_error:
|
||||||
|
logger.error(f"Error saving partial messages after disconnect: {save_error}")
|
||||||
|
# 通知前端中断(可能发送不到,但用于一致性)
|
||||||
|
try:
|
||||||
|
yield make_chunk(status="interrupted", message="对话已中断", meta=meta)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error streaming messages: {e}, {traceback.format_exc()}")
|
logger.error(f"Error streaming messages: {e}, {traceback.format_exc()}")
|
||||||
yield make_chunk(message=f"Error streaming messages: {e}", status="error")
|
yield make_chunk(message=f"Error streaming messages: {e}", status="error")
|
||||||
|
|||||||
@ -71,9 +71,9 @@
|
|||||||
v-model="userInput"
|
v-model="userInput"
|
||||||
:is-loading="isProcessing"
|
:is-loading="isProcessing"
|
||||||
:disabled="!currentAgent"
|
:disabled="!currentAgent"
|
||||||
:send-button-disabled="!userInput || !currentAgent || isProcessing"
|
:send-button-disabled="(!userInput || !currentAgent) && !isProcessing"
|
||||||
:placeholder="'输入问题...'"
|
:placeholder="'输入问题...'"
|
||||||
@send="handleSendMessage"
|
@send="handleSendOrStop"
|
||||||
@keydown="handleKeyDown"
|
@keydown="handleKeyDown"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -131,9 +131,9 @@
|
|||||||
v-model="userInput"
|
v-model="userInput"
|
||||||
:is-loading="isProcessing"
|
:is-loading="isProcessing"
|
||||||
:disabled="!currentAgent"
|
:disabled="!currentAgent"
|
||||||
:send-button-disabled="!userInput || !currentAgent || isProcessing"
|
:send-button-disabled="(!userInput || !currentAgent) && !isProcessing"
|
||||||
:placeholder="'输入问题...'"
|
:placeholder="'输入问题...'"
|
||||||
@send="handleSendMessage"
|
@send="handleSendOrStop"
|
||||||
@keydown="handleKeyDown"
|
@keydown="handleKeyDown"
|
||||||
/>
|
/>
|
||||||
<div class="bottom-actions">
|
<div class="bottom-actions">
|
||||||
@ -416,6 +416,11 @@ const _processStreamChunk = (chunk, threadId) => {
|
|||||||
fetchThreadMessages({ agentId: currentAgentId.value, threadId: threadId });
|
fetchThreadMessages({ agentId: currentAgentId.value, threadId: threadId });
|
||||||
resetOnGoingConv(threadId);
|
resetOnGoingConv(threadId);
|
||||||
break;
|
break;
|
||||||
|
case 'interrupted':
|
||||||
|
// 中断状态,刷新消息历史
|
||||||
|
fetchThreadMessages({ agentId: currentAgentId.value, threadId: threadId });
|
||||||
|
resetOnGoingConv(threadId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -726,6 +731,27 @@ const handleSendMessage = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 发送或中断
|
||||||
|
const handleSendOrStop = async () => {
|
||||||
|
const threadId = currentChatId.value;
|
||||||
|
const threadState = getThreadState(threadId);
|
||||||
|
if (isProcessing.value && threadState && threadState.streamAbortController) {
|
||||||
|
// 中断生成
|
||||||
|
threadState.streamAbortController.abort();
|
||||||
|
|
||||||
|
// 中断后刷新消息历史,确保显示最新的状态
|
||||||
|
try {
|
||||||
|
await fetchThreadMessages({ agentId: currentAgentId.value, threadId: threadId });
|
||||||
|
message.info('已中断对话生成');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('刷新消息历史失败:', error);
|
||||||
|
message.info('已中断对话生成');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await handleSendMessage();
|
||||||
|
};
|
||||||
|
|
||||||
// ==================== UI HANDLERS ====================
|
// ==================== UI HANDLERS ====================
|
||||||
const handleRenameChat = () => {
|
const handleRenameChat = () => {
|
||||||
if (!currentChatId.value || !currentThread.value) {
|
if (!currentChatId.value || !currentThread.value) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user