|
|
@@ -0,0 +1,56 @@
|
|
|
+from fastapi import APIRouter, HTTPException
|
|
|
+from pydantic import BaseModel
|
|
|
+from app.graphs.portrait_generation_graph import get_portrait_graph
|
|
|
+import logging
|
|
|
+
|
|
|
+logger = logging.getLogger(__name__)
|
|
|
+
|
|
|
+router = APIRouter(prefix="/api/portrait", tags=["portrait"])
|
|
|
+
|
|
|
+
|
|
|
+class PortraitGenerateRequest(BaseModel):
|
|
|
+ user_id: int
|
|
|
+ member_id: int | None = None
|
|
|
+ previous_portrait: str | None = None
|
|
|
+ profile_snapshot: dict | None = None
|
|
|
+ behavior_summary: dict | None = None
|
|
|
+
|
|
|
+
|
|
|
+@router.post("/generate")
|
|
|
+async def generate_portrait(req: PortraitGenerateRequest):
|
|
|
+ """AI 生成用户画像(首次生成)"""
|
|
|
+ try:
|
|
|
+ graph = get_portrait_graph()
|
|
|
+ state = {
|
|
|
+ "user_id": req.user_id,
|
|
|
+ "member_id": req.member_id,
|
|
|
+ "previous_portrait": None,
|
|
|
+ "profile_snapshot": req.profile_snapshot,
|
|
|
+ "behavior_summary": req.behavior_summary,
|
|
|
+ "portrait_text": None,
|
|
|
+ }
|
|
|
+ result = await graph.ainvoke(state)
|
|
|
+ return {"portrait_text": result["portrait_text"]}
|
|
|
+ except Exception as e:
|
|
|
+ logger.exception("画像生成失败")
|
|
|
+ raise HTTPException(status_code=500, detail=str(e))
|
|
|
+
|
|
|
+
|
|
|
+@router.post("/regenerate")
|
|
|
+async def regenerate_portrait(req: PortraitGenerateRequest):
|
|
|
+ """AI 重画用户画像(参考旧画像)"""
|
|
|
+ try:
|
|
|
+ graph = get_portrait_graph()
|
|
|
+ state = {
|
|
|
+ "user_id": req.user_id,
|
|
|
+ "member_id": req.member_id,
|
|
|
+ "previous_portrait": req.previous_portrait,
|
|
|
+ "profile_snapshot": req.profile_snapshot,
|
|
|
+ "behavior_summary": req.behavior_summary,
|
|
|
+ "portrait_text": None,
|
|
|
+ }
|
|
|
+ result = await graph.ainvoke(state)
|
|
|
+ return {"portrait_text": result["portrait_text"]}
|
|
|
+ except Exception as e:
|
|
|
+ logger.exception("画像重画失败")
|
|
|
+ raise HTTPException(status_code=500, detail=str(e))
|