fix: propagate real message IDs via SSE and fix regenerate model parameter
- Add message_id and user_message_id to SSE done events so frontend can replace temp IDs with real DB IDs, fixing "消息不存在" on regenerate - Replace Body(default=None) with RegenerateRequest Pydantic model for proper JSON body parsing, fixing 422 Unprocessable Content - Frontend always sends model in regenerate request body - Pass selected model through message-item → regenerateMessage chain - Various UI refinements to chat sidebar, quick questions, and layout Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+44
-17
@@ -282,9 +282,10 @@ async def stream_message(
|
||||
)
|
||||
db.add(assistant_message)
|
||||
db.commit()
|
||||
|
||||
yield f"data: {json.dumps({'type': 'done', 'session_id': session.id}, ensure_ascii=False)}\n\n"
|
||||
|
||||
db.refresh(assistant_message)
|
||||
|
||||
yield f"data: {json.dumps({'type': 'done', 'session_id': session.id, 'message_id': assistant_message.id, 'user_message_id': user_message.id}, ensure_ascii=False)}\n\n"
|
||||
|
||||
else:
|
||||
# 普通模式:使用LangChain 1.0对话链
|
||||
print(f"[DEBUG-CHAT] 普通模式 - 使用LangChain流式对话链")
|
||||
@@ -321,9 +322,10 @@ async def stream_message(
|
||||
)
|
||||
db.add(assistant_message)
|
||||
db.commit()
|
||||
|
||||
yield f"data: {json.dumps({'type': 'done', 'session_id': session.id}, ensure_ascii=False)}\n\n"
|
||||
|
||||
db.refresh(assistant_message)
|
||||
|
||||
yield f"data: {json.dumps({'type': 'done', 'session_id': session.id, 'message_id': assistant_message.id, 'user_message_id': user_message.id}, ensure_ascii=False)}\n\n"
|
||||
|
||||
except Exception as e:
|
||||
yield f"data: {json.dumps({'error': str(e)})}\n\n"
|
||||
finally:
|
||||
@@ -555,6 +557,11 @@ class MessageFeedbackRequest(BaseModel):
|
||||
feedback: str # like, dislike
|
||||
|
||||
|
||||
class RegenerateRequest(BaseModel):
|
||||
"""重新生成请求模型"""
|
||||
model: Optional[str] = None
|
||||
|
||||
|
||||
@router.put("/messages/{message_id}")
|
||||
async def edit_message(
|
||||
message_id: int,
|
||||
@@ -588,21 +595,40 @@ async def edit_message(
|
||||
async def regenerate_message(
|
||||
message_id: int,
|
||||
current_user: str = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
db: Session = Depends(get_db),
|
||||
request: RegenerateRequest = None,
|
||||
):
|
||||
"""重新生成AI回复"""
|
||||
# 获取原始消息
|
||||
original_message = db.query(ChatMessage).join(ChatSession).filter(
|
||||
"""重新生成AI回复 — 支持 user 和 assistant 消息 ID"""
|
||||
model = request.model if request else None
|
||||
# 查找目标消息
|
||||
target_message = db.query(ChatMessage).join(ChatSession).filter(
|
||||
ChatMessage.id == message_id,
|
||||
ChatMessage.role == "user",
|
||||
ChatSession.user_id == get_user_id_by_username(db, current_user)
|
||||
).first()
|
||||
|
||||
if not original_message:
|
||||
|
||||
if not target_message:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="消息不存在"
|
||||
)
|
||||
|
||||
# 如果传入的是 assistant 消息,找到同 session 中前一条 user 消息
|
||||
if target_message.role == "assistant":
|
||||
original_message = db.query(ChatMessage).filter(
|
||||
ChatMessage.session_id == target_message.session_id,
|
||||
ChatMessage.role == "user",
|
||||
ChatMessage.created_at < target_message.created_at
|
||||
).order_by(ChatMessage.created_at.desc()).first()
|
||||
|
||||
if not original_message:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="找不到对应的用户消息"
|
||||
)
|
||||
# 删除该 assistant 消息本身
|
||||
db.delete(target_message)
|
||||
else:
|
||||
original_message = target_message
|
||||
|
||||
# 删除该消息之后的所有消息
|
||||
later_messages = db.query(ChatMessage).filter(
|
||||
@@ -620,7 +646,8 @@ async def regenerate_message(
|
||||
original_message.content,
|
||||
original_message.session_id,
|
||||
db,
|
||||
None # No knowledge base filtering for regeneration
|
||||
None, # No knowledge base filtering for regeneration
|
||||
model
|
||||
)
|
||||
|
||||
# 创建新的AI回复
|
||||
@@ -679,7 +706,7 @@ async def feedback_message(
|
||||
return {"message": "反馈提交成功", "feedback": request.feedback}
|
||||
|
||||
|
||||
async def run_rag_workflow_with_context(question: str, session_id: int, db: Session, knowledge_base_ids: Optional[List[int]] = None) -> Dict[str, Any]:
|
||||
async def run_rag_workflow_with_context(question: str, session_id: int, db: Session, knowledge_base_ids: Optional[List[int]] = None, model: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""运行带上下文的RAG工作流"""
|
||||
try:
|
||||
# 获取会话历史消息作为上下文
|
||||
@@ -696,7 +723,7 @@ async def run_rag_workflow_with_context(question: str, session_id: int, db: Sess
|
||||
context_messages.append({"role": "assistant", "content": msg.content})
|
||||
|
||||
# 运行RAG工作流
|
||||
rag_chain = create_rag_chain(knowledge_base_ids=knowledge_base_ids)
|
||||
rag_chain = create_rag_chain(knowledge_base_ids=knowledge_base_ids, model=model)
|
||||
result = rag_chain.invoke(question)
|
||||
|
||||
# 如果有上下文,增强回答
|
||||
@@ -710,5 +737,5 @@ async def run_rag_workflow_with_context(question: str, session_id: int, db: Sess
|
||||
except Exception as e:
|
||||
print(f"RAG工作流执行失败: {str(e)}")
|
||||
# 降级到基础问答
|
||||
rag_chain = create_rag_chain()
|
||||
rag_chain = create_rag_chain(model=model)
|
||||
return rag_chain.invoke(question)
|
||||
|
||||
Reference in New Issue
Block a user