REMB / src /api /agent_api.py
Cuong2004's picture
update agent/mcp/tool, add algo jupyter
56e31ec
"""
Agent API Endpoints
New FastAPI router for Agent-based interactions
"""
from fastapi import APIRouter, HTTPException, UploadFile, File, Form
from pydantic import BaseModel
from typing import Optional, List, Dict, Any
import tempfile
import os
import logging
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/agent", tags=["agent"])
class AgentChatRequest(BaseModel):
"""Request model for agent chat"""
session_id: str
message: str
file_path: Optional[str] = None
boundary_coords: Optional[List[List[float]]] = None
class AgentChatResponse(BaseModel):
"""Response model for agent chat"""
status: str
response: str
tool_calls: List[Dict[str, Any]] = []
session_id: str
@router.post("/chat", response_model=AgentChatResponse)
async def agent_chat(request: AgentChatRequest):
"""
Chat with the REMB Agent
The agent can:
- Read and parse DXF files
- Generate optimized layouts
- Check regulatory compliance
- Export results to DXF
- Self-correct on errors
"""
try:
from src.agent import get_agent
agent = get_agent()
result = agent.invoke(
user_input=request.message,
session_id=request.session_id,
file_path=request.file_path,
boundary_coords=request.boundary_coords
)
return AgentChatResponse(**result)
except ValueError as e:
raise HTTPException(400, str(e))
except Exception as e:
logger.error(f"Agent chat error: {e}")
raise HTTPException(500, f"Agent error: {str(e)}")
@router.post("/process-file")
async def agent_process_file(
file: UploadFile = File(...),
message: str = Form(default="Analyze this site and suggest optimal layouts"),
session_id: str = Form(default="default")
):
"""
Upload a CAD file and process with the agent
The agent will:
1. Parse the file
2. Analyze the site
3. Generate layout options
4. Check compliance
5. Return comprehensive results
"""
if not file.filename:
raise HTTPException(400, "No file provided")
# Save uploaded file
try:
content = await file.read()
suffix = ".dwg" if file.filename.lower().endswith(".dwg") else ".dxf"
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
tmp.write(content)
tmp_path = tmp.name
# Process with agent
from src.agent import get_agent
agent = get_agent()
result = agent.invoke(
user_input=f"[File uploaded: {file.filename}]\n{message}",
session_id=session_id,
file_path=tmp_path
)
# Clean up temp file
try:
os.unlink(tmp_path)
except:
pass
return {
"status": result.get("status"),
"response": result.get("response"),
"tool_calls": result.get("tool_calls", []),
"session_id": session_id,
"file_processed": file.filename
}
except Exception as e:
logger.error(f"File processing error: {e}")
raise HTTPException(500, f"Processing error: {str(e)}")
@router.get("/health")
async def agent_health():
"""Check agent status"""
try:
from src.agent import get_agent
from src.tools import all_tools
agent = get_agent()
return {
"status": "healthy",
"agent_type": "ReAct",
"model": agent.model_name,
"tools_available": len(all_tools),
"tool_names": [t.name for t in all_tools]
}
except Exception as e:
return {
"status": "error",
"message": str(e)
}