fix(workflow): add reasoning content, suggested questions, citations and audio status support
- Introduce `reasoning_content`, `suggested_questions`, `citations`, and `audio_status` fields in conversation and app response schemas - Conditionally set `audio_status` to `"pending"` only when `audio_url` is present - Replace `model_dump` override with `@model_serializer(mode="wrap")` for cleaner serialization logic - Change knowledge base validation failure from `RuntimeError` to warning + `continue` to avoid halting retrieval on invalid KB
This commit is contained in:
@@ -334,7 +334,8 @@ class KnowledgeRetrievalNode(BaseNode):
|
||||
for kb_config in knowledge_bases:
|
||||
db_knowledge = knowledge_repository.get_knowledge_by_id(db=db, knowledge_id=kb_config.kb_id)
|
||||
if not (db_knowledge and db_knowledge.chunk_num > 0 and db_knowledge.status == 1):
|
||||
raise RuntimeError("The knowledge base does not exist or access is denied.")
|
||||
logger.warning("The knowledge base does not exist or access is denied.")
|
||||
continue
|
||||
tasks.append(self.knowledge_retrieval(db, query, db_knowledge, kb_config))
|
||||
if tasks:
|
||||
result = await asyncio.gather(*tasks)
|
||||
|
||||
@@ -3,7 +3,7 @@ import uuid
|
||||
from typing import Optional, Any, List, Dict, Union
|
||||
from enum import Enum, StrEnum
|
||||
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer, field_validator
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer, field_validator, model_serializer
|
||||
|
||||
from app.schemas.workflow_schema import WorkflowConfigCreate
|
||||
|
||||
@@ -661,9 +661,11 @@ class DraftRunResponse(BaseModel):
|
||||
suggested_questions: List[str] = Field(default_factory=list, description="下一步建议问题")
|
||||
citations: List[Dict[str, Any]] = Field(default_factory=list, description="引用来源")
|
||||
audio_url: Optional[str] = Field(default=None, description="TTS 语音URL")
|
||||
audio_status: Optional[str] = Field(default=None, description="TTS 语音状态")
|
||||
|
||||
def model_dump(self, **kwargs):
|
||||
data = super().model_dump(**kwargs)
|
||||
@model_serializer(mode="wrap")
|
||||
def _serialize(self, handler):
|
||||
data = handler(self)
|
||||
if not data.get("reasoning_content"):
|
||||
data.pop("reasoning_content", None)
|
||||
return data
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import uuid
|
||||
import datetime
|
||||
from typing import Optional, Dict, Any, List
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer, model_serializer
|
||||
|
||||
# 导入 FileInput(用于体验运行)
|
||||
from app.schemas.app_schema import FileInput
|
||||
@@ -94,6 +94,18 @@ class ChatResponse(BaseModel):
|
||||
message_id: str
|
||||
usage: Optional[Dict[str, Any]] = None
|
||||
elapsed_time: Optional[float] = None
|
||||
reasoning_content: Optional[str] = None
|
||||
suggested_questions: Optional[List[str]] = None
|
||||
citations: Optional[List[Any]] = None
|
||||
audio_url: Optional[str] = None
|
||||
audio_status: Optional[str] = None
|
||||
|
||||
@model_serializer(mode="wrap")
|
||||
def _serialize(self, handler):
|
||||
data = handler(self)
|
||||
if not data.get("reasoning_content"):
|
||||
data.pop("reasoning_content", None)
|
||||
return data
|
||||
|
||||
|
||||
# ---------- Conversation Summary Schemas ----------
|
||||
|
||||
@@ -317,7 +317,7 @@ class AppChatService:
|
||||
"suggested_questions": suggested_questions,
|
||||
"citations": filtered_citations,
|
||||
"audio_url": audio_url,
|
||||
"audio_status": "pending"
|
||||
"audio_status": "pending" if audio_url else None
|
||||
}
|
||||
|
||||
async def agnet_chat_stream(
|
||||
|
||||
@@ -754,7 +754,7 @@ class AgentRunService:
|
||||
) if not sub_agent else [],
|
||||
"citations": filtered_citations,
|
||||
"audio_url": audio_url,
|
||||
"audio_status": "pending"
|
||||
"audio_status": "pending" if audio_url else None
|
||||
}
|
||||
|
||||
logger.info(
|
||||
|
||||
Reference in New Issue
Block a user