批次4死代码大扫除: 删triage三件套(H5零挂载)+ /approval/keywords端点 + scheduler.py孤儿模块 + 3个.bak文件 + get_reply_stream(~96行)
This commit is contained in:
@@ -231,102 +231,9 @@ class AIService:
|
||||
# --------------------------------------------------------------------------
|
||||
# 流式调用:SSE 流式返回(供 WebSocket 推送给前端)
|
||||
# --------------------------------------------------------------------------
|
||||
async def get_reply_stream(
|
||||
self,
|
||||
message: str,
|
||||
conversation_id: Optional[str] = None,
|
||||
user_id: Optional[str] = None,
|
||||
) -> AsyncGenerator[Dict[str, Any], None]:
|
||||
"""调用 Dify API 获取流式 AI 回复(SSE),逐块 yield 给调用方。
|
||||
|
||||
Yields:
|
||||
Dict: {"delta": str, "finished": bool, "conversation_id": str, "hit": bool|None}
|
||||
- 流式中间块:{"delta": 增量, "finished": False, "hit": None}
|
||||
- 终态块:{"delta": "", "finished": True, "hit": 命中判断}
|
||||
|
||||
实现:
|
||||
- stream=True 走 SSE,解析 data: {...} 行,逐块 yield delta
|
||||
- 流结束后用完整内容整体判断 hit(_check_knowledge_hit)
|
||||
容错:若 Dify 不支持流式 / 超时 / 非 SSE 格式,catch 后 fallback 到
|
||||
get_reply 非流式,yield 一次完整内容(前端退化为"整段到达",
|
||||
功能不破,仅无逐字动画)。
|
||||
"""
|
||||
payload = {
|
||||
"model": "Chat",
|
||||
"messages": [{"role": "user", "content": message}],
|
||||
"stream": True,
|
||||
"temperature": 0.1,
|
||||
}
|
||||
if conversation_id:
|
||||
payload["conversation_id"] = conversation_id
|
||||
if user_id:
|
||||
payload["user"] = user_id
|
||||
|
||||
try:
|
||||
client = await self._get_client()
|
||||
full_parts: list = []
|
||||
dify_conv_id = conversation_id or ""
|
||||
async with client.stream("POST", self.api_url, json=payload) as response:
|
||||
response.raise_for_status()
|
||||
async for line in response.aiter_lines():
|
||||
if not line:
|
||||
continue
|
||||
line = line.strip()
|
||||
if not line.startswith("data:"):
|
||||
continue
|
||||
data = line[5:].strip()
|
||||
if data == "[DONE]":
|
||||
break
|
||||
try:
|
||||
chunk = json.loads(data)
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
# OpenAI / Dify SSE 格式:choices[0].delta.content
|
||||
try:
|
||||
delta = chunk["choices"][0]["delta"].get("content", "")
|
||||
except (KeyError, IndexError, TypeError):
|
||||
delta = ""
|
||||
if delta:
|
||||
full_parts.append(delta)
|
||||
yield {
|
||||
"delta": delta,
|
||||
"finished": False,
|
||||
"conversation_id": dify_conv_id,
|
||||
"hit": None,
|
||||
}
|
||||
# Dify 可能在流式块里给出 conversation_id
|
||||
cid = chunk.get("conversation_id")
|
||||
if cid:
|
||||
dify_conv_id = cid
|
||||
|
||||
# 流结束:用完整内容判断命中
|
||||
full_content = "".join(full_parts)
|
||||
hit = self._check_knowledge_hit(full_content) if full_content else False
|
||||
yield {
|
||||
"delta": "",
|
||||
"finished": True,
|
||||
"conversation_id": dify_conv_id,
|
||||
"hit": hit,
|
||||
}
|
||||
except Exception as e:
|
||||
# 流式不可用(dify2openai 不支持 / 超时 / 非 SSE),回退非流式
|
||||
logger.warning(f"Dify 流式失败,回退非流式: {e}")
|
||||
try:
|
||||
result = await self.get_reply(message, conversation_id, user_id)
|
||||
yield {
|
||||
"delta": result["content"],
|
||||
"finished": True,
|
||||
"conversation_id": result["conversation_id"],
|
||||
"hit": result["hit"],
|
||||
}
|
||||
except Exception as e2:
|
||||
logger.error(f"Dify 流式与非流式均失败: {e2}")
|
||||
yield {
|
||||
"delta": "⚠️ AI 服务异常,请输入「IT」转人工或稍后重试。",
|
||||
"finished": True,
|
||||
"conversation_id": conversation_id or "",
|
||||
"hit": False,
|
||||
}
|
||||
# v4.0 批次4:get_reply_stream 已删除(~96 行)
|
||||
# v2.0 起 AI 回复改为 blocking + JSON 结构化(get_structured_reply),
|
||||
# 流式 SSE 路径零调用,属死代码。
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 结构化调用:blocking 模式,返回解析后的 JSON {text, action, options}
|
||||
|
||||
Reference in New Issue
Block a user