ForcePilot/src/routers/chat_router.py

111 lines
3.8 KiB
Python
Raw Normal View History

2024-10-02 20:11:28 +08:00
import json
import asyncio
2024-10-24 20:08:23 +08:00
from fastapi import APIRouter, Body
from fastapi.responses import StreamingResponse, Response
2024-10-02 20:11:28 +08:00
from src.core import HistoryManager
2025-03-06 23:55:20 +08:00
from src.core.startup import startup, executor
2025-02-27 19:35:25 +08:00
from src.utils.logging_config import logger
2024-10-02 20:11:28 +08:00
chat = APIRouter(prefix="/chat")
2025-03-06 23:55:20 +08:00
2024-10-02 20:11:28 +08:00
@chat.get("/")
async def chat_get():
return "Chat Get!"
@chat.post("/")
def chat_post(
query: str = Body(...),
meta: dict = Body(None),
history: list = Body(...),
cur_res_id: str = Body(...)):
2024-10-02 20:11:28 +08:00
history_manager = HistoryManager(history)
2025-02-28 00:27:58 +08:00
logger.debug(f"Received query: {query} with meta: {meta}")
2024-10-02 20:11:28 +08:00
2025-02-23 16:39:52 +08:00
def make_chunk(content=None, **kwargs):
return json.dumps({
"response": content,
"model_name": startup.config.model_name,
2024-10-23 16:24:29 +08:00
"meta": meta,
2025-02-23 16:39:52 +08:00
**kwargs
}, ensure_ascii=False).encode('utf-8') + b"\n"
2024-10-02 20:11:28 +08:00
def need_retrieve(meta):
return meta.get("use_web") or meta.get("use_graph") or meta.get("db_name")
def generate_response():
modified_query = query
2025-02-23 16:39:52 +08:00
refs = None
# 处理知识库检索
if meta and need_retrieve(meta):
chunk = make_chunk(status="searching")
yield chunk
2025-02-23 16:39:52 +08:00
try:
modified_query, refs = startup.retriever(modified_query, history_manager.messages, meta)
except Exception as e:
logger.error(f"Retriever error: {e}")
yield make_chunk(message=f"Retriever error: {e}", status="error")
return
2025-02-25 21:26:55 +08:00
yield make_chunk(status="generating")
messages = history_manager.get_history_with_msg(modified_query, max_rounds=meta.get('history_round'))
history_manager.add_user(query) # 注意这里使用原始查询
2024-10-02 20:11:28 +08:00
content = ""
reasoning_content = ""
2025-02-25 21:26:55 +08:00
try:
for delta in startup.model.predict(messages, stream=True):
if not delta.content and hasattr(delta, 'reasoning_content'):
reasoning_content += delta.reasoning_content or ""
chunk = make_chunk(reasoning_content=reasoning_content, status="reasoning")
yield chunk
continue
# 文心一言
if hasattr(delta, 'is_full') and delta.is_full:
content = delta.content
else:
content += delta.content or ""
chunk = make_chunk(content=content, status="loading")
yield chunk
2024-10-02 20:11:28 +08:00
2025-02-25 21:26:55 +08:00
logger.debug(f"Final response: {content}")
logger.debug(f"Final reasoning response: {reasoning_content}")
yield make_chunk(content=content,
status="finished",
history=history_manager.update_ai(content),
refs=refs)
except Exception as e:
logger.error(f"Model error: {e}")
yield make_chunk(message=f"Model error: {e}", status="error")
return
2024-10-02 20:11:28 +08:00
return StreamingResponse(generate_response(), media_type='application/json')
@chat.post("/call")
async def call(query: str = Body(...), meta: dict = Body(None)):
async def predict_async(query):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(executor, startup.model.predict, query)
response = await predict_async(query)
2024-10-02 20:11:28 +08:00
logger.debug({"query": query, "response": response.content})
return {"response": response.content}
@chat.post("/call_lite")
async def call(query: str = Body(...), meta: dict = Body(None)):
async def predict_async(query):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(executor, startup.model_lite.predict, query)
response = await predict_async(query)
logger.debug({"query": query, "response": response.content})
2025-02-28 00:27:58 +08:00
return {"response": response.content}