2024-10-02 20:11:28 +08:00
|
|
|
import json
|
2024-10-14 22:10:56 +08:00
|
|
|
import asyncio
|
2025-03-17 19:58:00 +08:00
|
|
|
import traceback
|
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-16 01:11:13 +08:00
|
|
|
from src import executor, config, retriever
|
|
|
|
|
from src.models import select_model
|
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-14 22:10:56 +08:00
|
|
|
|
2024-10-02 20:11:28 +08:00
|
|
|
|
|
|
|
|
@chat.get("/")
|
|
|
|
|
async def chat_get():
|
|
|
|
|
return "Chat Get!"
|
|
|
|
|
|
|
|
|
|
@chat.post("/")
|
2024-10-14 22:10:56 +08:00
|
|
|
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
|
|
|
|
2025-03-16 01:11:13 +08:00
|
|
|
model = select_model(config)
|
|
|
|
|
meta["server_model_name"] = model.model_name
|
2024-10-14 22:10:56 +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):
|
2024-10-15 00:38:24 +08:00
|
|
|
return json.dumps({
|
|
|
|
|
"response": content,
|
2025-03-16 01:11:13 +08:00
|
|
|
"model_name": config.model_name,
|
2024-10-23 16:24:29 +08:00
|
|
|
"meta": meta,
|
2025-02-23 16:39:52 +08:00
|
|
|
**kwargs
|
2024-10-15 00:38:24 +08:00
|
|
|
}, ensure_ascii=False).encode('utf-8') + b"\n"
|
2024-10-02 20:11:28 +08:00
|
|
|
|
2025-02-24 19:43:40 +08:00
|
|
|
def need_retrieve(meta):
|
|
|
|
|
return meta.get("use_web") or meta.get("use_graph") or meta.get("db_name")
|
|
|
|
|
|
2024-10-14 22:10:56 +08:00
|
|
|
def generate_response():
|
2025-02-20 01:26:12 +08:00
|
|
|
modified_query = query
|
2025-02-23 16:39:52 +08:00
|
|
|
refs = None
|
2024-10-15 00:38:24 +08:00
|
|
|
|
2025-02-20 01:26:12 +08:00
|
|
|
# 处理知识库检索
|
2025-02-24 19:43:40 +08:00
|
|
|
if meta and need_retrieve(meta):
|
2025-02-20 01:26:12 +08:00
|
|
|
chunk = make_chunk(status="searching")
|
2024-10-15 00:38:24 +08:00
|
|
|
yield chunk
|
|
|
|
|
|
2025-02-23 16:39:52 +08:00
|
|
|
try:
|
2025-03-16 01:11:13 +08:00
|
|
|
modified_query, refs = retriever(modified_query, history_manager.messages, meta)
|
2025-02-23 16:39:52 +08:00
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"Retriever error: {e}")
|
|
|
|
|
yield make_chunk(message=f"Retriever error: {e}", status="error")
|
|
|
|
|
return
|
2024-10-15 00:38:24 +08:00
|
|
|
|
2025-02-25 21:26:55 +08:00
|
|
|
yield make_chunk(status="generating")
|
|
|
|
|
|
2025-02-20 01:26:12 +08:00
|
|
|
messages = history_manager.get_history_with_msg(modified_query, max_rounds=meta.get('history_round'))
|
|
|
|
|
history_manager.add_user(query) # 注意这里使用原始查询
|
2024-10-15 00:38:24 +08:00
|
|
|
|
2024-10-02 20:11:28 +08:00
|
|
|
content = ""
|
2025-02-20 01:26:12 +08:00
|
|
|
reasoning_content = ""
|
2025-02-25 21:26:55 +08:00
|
|
|
try:
|
2025-03-16 01:11:13 +08:00
|
|
|
for delta in model.predict(messages, stream=True):
|
2025-02-25 21:26:55 +08:00
|
|
|
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")
|
2025-02-20 01:26:12 +08:00
|
|
|
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:
|
2025-03-17 19:58:00 +08:00
|
|
|
logger.error(f"Model error: {e}, {traceback.format_exc()}")
|
2025-02-25 21:26:55 +08:00
|
|
|
yield make_chunk(message=f"Model error: {e}", status="error")
|
|
|
|
|
return
|
2025-02-20 01:26:12 +08:00
|
|
|
|
2024-10-02 20:11:28 +08:00
|
|
|
return StreamingResponse(generate_response(), media_type='application/json')
|
|
|
|
|
|
|
|
|
|
@chat.post("/call")
|
2024-10-14 22:10:56 +08:00
|
|
|
async def call(query: str = Body(...), meta: dict = Body(None)):
|
2025-03-16 01:11:13 +08:00
|
|
|
model = select_model(config, model_provider=meta.get("model_provider"), model_name=meta.get("model_name"))
|
2024-10-14 22:10:56 +08:00
|
|
|
async def predict_async(query):
|
|
|
|
|
loop = asyncio.get_event_loop()
|
2025-03-16 01:11:13 +08:00
|
|
|
return await loop.run_in_executor(executor, model.predict, query)
|
2024-10-14 22:10:56 +08:00
|
|
|
|
|
|
|
|
response = await predict_async(query)
|
2024-10-02 20:11:28 +08:00
|
|
|
logger.debug({"query": query, "response": response.content})
|
|
|
|
|
|
2024-10-14 22:10:56 +08:00
|
|
|
return {"response": response.content}
|
|
|
|
|
|
2025-02-20 01:26:12 +08:00
|
|
|
@chat.post("/call_lite")
|
|
|
|
|
async def call(query: str = Body(...), meta: dict = Body(None)):
|
|
|
|
|
async def predict_async(query):
|
|
|
|
|
loop = asyncio.get_event_loop()
|
2025-03-16 01:11:13 +08:00
|
|
|
model_provider = meta.get("model_provider", config.model_provider_lite)
|
|
|
|
|
model_name = meta.get("model_name", config.model_name_lite)
|
|
|
|
|
model = select_model(config, model_provider=model_provider, model_name=model_name)
|
|
|
|
|
return await loop.run_in_executor(executor, model.predict, query)
|
2025-02-20 01:26:12 +08:00
|
|
|
|
|
|
|
|
response = await predict_async(query)
|
|
|
|
|
logger.debug({"query": query, "response": response.content})
|
|
|
|
|
|
2025-02-28 00:27:58 +08:00
|
|
|
return {"response": response.content}
|