agents.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
  2. from typing import List, Optional
  3. import logging
  4. from pydantic import BaseModel
  5. from app.db.session import get_db
  6. from app.schemas import MessageResponse
  7. from app.crud import create_message, get_forum_messages
  8. from app.agent.agent import ParticipantAgent
  9. from app.agent.memory import SharedMemory
  10. router = APIRouter()
  11. logger = logging.getLogger(__name__)
  12. class AgentChatRequest(BaseModel):
  13. agent_name: str
  14. persona_json: dict
  15. context_messages: List[dict]
  16. theme: str = "AI对未来的影响"
  17. class AgentChatResponse(BaseModel):
  18. content: str
  19. thought: Optional[dict] = None
  20. @router.post("/chat", response_model=AgentChatResponse)
  21. async def chat_with_agent(request: AgentChatRequest):
  22. """
  23. Directly invoke an agent to think and speak based on provided context.
  24. This is a stateless endpoint wrapper around the ParticipantAgent logic.
  25. """
  26. # 1. Reconstruct Agent
  27. try:
  28. agent = ParticipantAgent(
  29. name=request.agent_name,
  30. persona=request.persona_json,
  31. n_participants=3, # Default, doesn't affect single-turn much
  32. theme=request.theme
  33. )
  34. except Exception:
  35. logger.exception("Failed to initialize agent")
  36. raise HTTPException(status_code=400, detail="Failed to initialize agent")
  37. # 2. Reconstruct Context
  38. # We need to convert the list of dicts into the string format expected by agent.think/speak
  39. # Or better, use SharedMemory to generate it if we want to reuse logic exactly.
  40. memory = SharedMemory(n_participants=3)
  41. for msg in request.context_messages:
  42. memory.add_message(msg.get("speaker", "Unknown"), msg.get("content", ""))
  43. context_str = memory.get_context_str()
  44. # 3. Think
  45. thought = agent.think(context_str)
  46. if not thought:
  47. raise HTTPException(status_code=500, detail="Agent failed to think")
  48. # 4. Speak
  49. # If agent decides to listen, we return empty content but include thought
  50. if thought.get("action") == "listen":
  51. return AgentChatResponse(content="", thought=thought)
  52. # If speaking
  53. response_stream = agent.speak(thought, context_str)
  54. full_content = ""
  55. if response_stream:
  56. for token in response_stream:
  57. if token:
  58. full_content += token
  59. return AgentChatResponse(content=full_content, thought=thought)