fix: 更新聊天代理处理逻辑,增强敏感内容检测和中断提示
- 在 chat_agent 函数中,优化了敏感内容检测后的响应,添加了时间成本的记录。 - 修改了前端 AgentChatComponent 和 AgentMessageComponent,以正确处理和显示敏感内容中断的提示信息。 - 移除了不必要的代码注释和冗余逻辑,提升了代码可读性。
This commit is contained in:
parent
685f48272b
commit
214bcb8d3e
@ -375,7 +375,6 @@ async def get_agent(current_user: User = Depends(get_required_user)):
|
||||
return {"agents": agents}
|
||||
|
||||
|
||||
# TODO:[未完成]这个thread_id在前端是直接生成的1234,最好传入thread_id时做校验只允许uuid4
|
||||
@chat.post("/agent/{agent_id}")
|
||||
async def chat_agent(
|
||||
agent_id: str,
|
||||
@ -472,7 +471,8 @@ async def chat_agent(
|
||||
if conf.enable_content_guard and await content_guard.check_with_keywords(full_msg.content[-20:]):
|
||||
logger.warning("Sensitive content detected in stream")
|
||||
await save_partial_message(conv_manager, thread_id, full_msg, "content_guard_blocked")
|
||||
yield make_chunk(message="检测到敏感内容,已中断输出", status="error")
|
||||
meta["time_cost"] = asyncio.get_event_loop().time() - start_time
|
||||
yield make_chunk(status="interrupted", message="检测到敏感内容,已中断输出", meta=meta)
|
||||
return
|
||||
|
||||
yield make_chunk(content=msg.content, msg=msg.model_dump(), metadata=metadata, status="loading")
|
||||
@ -487,7 +487,8 @@ async def chat_agent(
|
||||
):
|
||||
logger.warning("Sensitive content detected in final message")
|
||||
await save_partial_message(conv_manager, thread_id, full_msg, "content_guard_blocked")
|
||||
yield make_chunk(message="检测到敏感内容,已中断输出", status="error")
|
||||
meta["time_cost"] = asyncio.get_event_loop().time() - start_time
|
||||
yield make_chunk(status="interrupted", message="检测到敏感内容,已中断输出", meta=meta)
|
||||
return
|
||||
|
||||
# After streaming finished, check for interrupts and save messages
|
||||
@ -512,16 +513,6 @@ async def chat_agent(
|
||||
# 客户端主动中断连接,检查中断并保存已生成的部分内容
|
||||
logger.warning(f"Client disconnected, cancelling stream: {e}")
|
||||
|
||||
# 断开连接时不检查中断,直接保存部分消息
|
||||
langgraph_config = {"configurable": input_context}
|
||||
|
||||
# 尝试从 LangGraph state 保存消息(可能没有,因为中断了)
|
||||
await save_messages_from_langgraph_state(
|
||||
agent_instance=agent,
|
||||
thread_id=thread_id,
|
||||
conv_mgr=conv_manager,
|
||||
config_dict=langgraph_config,
|
||||
)
|
||||
|
||||
# 如果有手动维护的 full_msg,直接保存到数据库
|
||||
if full_msg:
|
||||
@ -539,16 +530,6 @@ async def chat_agent(
|
||||
except Exception as e:
|
||||
logger.error(f"Error streaming messages: {e}, {traceback.format_exc()}")
|
||||
|
||||
# 异常情况下也不检查中断,直接保存部分消息
|
||||
langgraph_config = {"configurable": input_context}
|
||||
|
||||
# 尝试从 LangGraph state 保存消息(可能没有,因为异常了)
|
||||
await save_messages_from_langgraph_state(
|
||||
agent_instance=agent,
|
||||
thread_id=thread_id,
|
||||
conv_mgr=conv_manager,
|
||||
config_dict=langgraph_config,
|
||||
)
|
||||
|
||||
# 如果有手动维护的 full_msg,直接保存到数据库
|
||||
if full_msg:
|
||||
|
||||
@ -64,7 +64,7 @@ class AttachmentMiddleware(AgentMiddleware[AttachmentState]):
|
||||
self, request: ModelRequest, handler: Callable[[ModelRequest], ModelResponse]
|
||||
) -> ModelResponse:
|
||||
# Read from State: get uploaded files metadata
|
||||
logger.debug(f"inject_attachment_context: request.state = {request.state}")
|
||||
# logger.debug(f"inject_attachment_context: request.state = {request.state}")
|
||||
attachments = request.state.get("attachments", [])
|
||||
|
||||
if attachments:
|
||||
|
||||
@ -470,7 +470,7 @@ const resetOnGoingConv = (threadId = null, preserveMessages = false) => {
|
||||
};
|
||||
|
||||
const _processStreamChunk = (chunk, threadId) => {
|
||||
const { status, msg, request_id, message } = chunk;
|
||||
const { status, msg, request_id, message: chunkMessage } = chunk;
|
||||
const threadState = getThreadState(threadId);
|
||||
// console.log('Processing stream chunk:', chunk, 'for thread:', threadId);
|
||||
|
||||
@ -489,7 +489,7 @@ const _processStreamChunk = (chunk, threadId) => {
|
||||
}
|
||||
return false;
|
||||
case 'error':
|
||||
handleChatError({ message }, 'stream');
|
||||
handleChatError({ message: chunkMessage }, 'stream');
|
||||
// Stop the loading indicator
|
||||
if (threadState) {
|
||||
threadState.isStreaming = false;
|
||||
@ -525,6 +525,10 @@ const _processStreamChunk = (chunk, threadId) => {
|
||||
if (threadState) {
|
||||
threadState.isStreaming = false;
|
||||
}
|
||||
// 如果有 message 字段,显示提示(例如:敏感内容检测)
|
||||
if (chunkMessage) {
|
||||
message.info(chunkMessage);
|
||||
}
|
||||
fetchThreadMessages({ agentId: currentAgentId.value, threadId: threadId })
|
||||
.finally(() => {
|
||||
resetOnGoingConv(threadId, true);
|
||||
|
||||
@ -30,9 +30,10 @@
|
||||
<div v-else-if="parsedData.reasoning_content" class="empty-block"></div>
|
||||
|
||||
<!-- 错误提示块 -->
|
||||
<div v-if="message.error_type" class="error-hint" :class="{ 'error-interrupted': message.error_type === 'interrupted', 'error-unexpect': message.error_type === 'unexpect' }">
|
||||
<div v-if="message.error_type" class="error-hint">
|
||||
<span v-if="message.error_type === 'interrupted'">回答生成已中断</span>
|
||||
<span v-else-if="message.error_type === 'unexpect'">生成过程中出现异常</span>
|
||||
<span v-else-if="message.error_type === 'content_guard_blocked'">检测到敏感内容,已中断输出</span>
|
||||
</div>
|
||||
|
||||
<div v-if="validToolCalls && validToolCalls.length > 0" class="tool-calls-container">
|
||||
@ -365,19 +366,9 @@ const toggleToolCall = (toolCallId) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
&.error-interrupted {
|
||||
background-color: #fffbeb;
|
||||
// border: 1px solid #fbbf24;
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
&.error-unexpect {
|
||||
background-color: #fef2f2;
|
||||
// border: 1px solid #f87171;
|
||||
color: #991b1b;
|
||||
}
|
||||
|
||||
background-color: #fef2f2;
|
||||
// border: 1px solid #f87171;
|
||||
color: #991b1b;
|
||||
span {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user