|
@@ -1,18 +1,82 @@
|
|
|
-from fastapi import APIRouter, HTTPException, Depends
|
|
|
|
|
-from fastapi.responses import StreamingResponse
|
|
|
|
|
-from typing import Annotated
|
|
|
|
|
-from fastapi import Query
|
|
|
|
|
|
|
+from fastapi import APIRouter, HTTPException
|
|
|
|
|
+from datetime import datetime
|
|
|
|
|
|
|
|
from ..core.ark_client import config, client
|
|
from ..core.ark_client import config, client
|
|
|
-from ..schemas.chat import ChatRequest, ChatResponse
|
|
|
|
|
-from ..dependencies.auth import resolve_username
|
|
|
|
|
|
|
+from ..schemas.chat import ChatMessage, ChatResponse, CircleRequest
|
|
|
|
|
+from ..db.souyue_mongo import get_mblog_by_id
|
|
|
|
|
+from ..db.mongo import get_circle_prompt
|
|
|
|
|
|
|
|
router = APIRouter()
|
|
router = APIRouter()
|
|
|
|
|
|
|
|
|
|
|
|
|
-@router.post("/chat", response_model=ChatResponse)
|
|
|
|
|
-async def chat(
|
|
|
|
|
- request: ChatRequest,
|
|
|
|
|
- username: Annotated[str, Depends(resolve_username)],
|
|
|
|
|
-):
|
|
|
|
|
- pass
|
|
|
|
|
|
|
+def _build_prompt(product_text: str, prompt_config: dict) -> str:
|
|
|
|
|
+ name = prompt_config.get("name", "兴趣圈")
|
|
|
|
|
+ role = prompt_config.get("role", "活跃用户")
|
|
|
|
|
+ style = prompt_config.get("style", "自然亲切,有活人感")
|
|
|
|
|
+ keywords: list = prompt_config.get("keywords") or []
|
|
|
|
|
+ forbidden: list = prompt_config.get("forbidden") or []
|
|
|
|
|
+
|
|
|
|
|
+ lines = [
|
|
|
|
|
+ f"你是{role},活跃在{name}兴趣圈。",
|
|
|
|
|
+ "请根据以下帖子信息,生成一条10-30字的评论,要求:",
|
|
|
|
|
+ "1. 内容指向性强,结合帖子具体内容",
|
|
|
|
|
+ f"2. 风格:{style}",
|
|
|
|
|
+ ]
|
|
|
|
|
+ seq = 3
|
|
|
|
|
+ if keywords:
|
|
|
|
|
+ lines.append(f"{seq}. 适当融入关键词(自然使用):{', '.join(keywords)}")
|
|
|
|
|
+ seq += 1
|
|
|
|
|
+ if forbidden:
|
|
|
|
|
+ lines.append(f"{seq}. 禁止使用以下词语:{', '.join(forbidden)}")
|
|
|
|
|
+ seq += 1
|
|
|
|
|
+ lines.append(f"{seq}. 语言自然,不要暴露你是AI")
|
|
|
|
|
+ lines.append(f"\n帖子内容:{product_text}")
|
|
|
|
|
+
|
|
|
|
|
+ return "\n".join(lines)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# 评论帖子的马甲机器人,无状态,支持批量对多个帖子智能回复
|
|
|
|
|
+@router.post("/airesp", response_model=ChatResponse)
|
|
|
|
|
+async def generate_circle_comment(request: CircleRequest):
|
|
|
|
|
+ doc = get_mblog_by_id(request.id)
|
|
|
|
|
+ if not doc:
|
|
|
|
|
+ raise HTTPException(status_code=404, detail="帖子不存在")
|
|
|
|
|
+
|
|
|
|
|
+ title = doc.get("title", "")
|
|
|
|
|
+ brief = doc.get("brief", "")
|
|
|
|
|
+ nickname = doc.get("nickname", "")
|
|
|
|
|
+ app_name = doc.get("appName", "")
|
|
|
|
|
+ images: list = doc.get("images") or []
|
|
|
|
|
+
|
|
|
|
|
+ product_text = f"主题:{title}\n摘要:{brief}\n发布者:{nickname}"
|
|
|
|
|
+ if images:
|
|
|
|
|
+ product_text += "\n图片:\n" + "\n".join(images)
|
|
|
|
|
+
|
|
|
|
|
+ prompt_config = get_circle_prompt(app_name)
|
|
|
|
|
+ prompt = _build_prompt(product_text, prompt_config)
|
|
|
|
|
+
|
|
|
|
|
+ response = client.responses.create(
|
|
|
|
|
+ model=config.MODEL_NAME,
|
|
|
|
|
+ input=[{"role": "user", "content": prompt}],
|
|
|
|
|
+ stream=False,
|
|
|
|
|
+ store=False,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ message_content = ""
|
|
|
|
|
+ for item in response.output:
|
|
|
|
|
+ if hasattr(item, 'type') and item.type == 'message' and hasattr(item, 'content'):
|
|
|
|
|
+ if isinstance(item.content, list):
|
|
|
|
|
+ for content_item in item.content:
|
|
|
|
|
+ if hasattr(content_item, 'text'):
|
|
|
|
|
+ message_content += content_item.text
|
|
|
|
|
+ else:
|
|
|
|
|
+ message_content += str(item.content)
|
|
|
|
|
+
|
|
|
|
|
+ if not message_content:
|
|
|
|
|
+ raise HTTPException(status_code=500, detail="AI未能生成评论")
|
|
|
|
|
+
|
|
|
|
|
+ return ChatResponse(
|
|
|
|
|
+ message=ChatMessage(role="assistant", content=message_content, timestamp=datetime.now()),
|
|
|
|
|
+ model=response.model,
|
|
|
|
|
+ usage=response.usage.model_dump() if response.usage else None,
|
|
|
|
|
+ )
|