import os from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv()) from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware import httpx from src.agent import BasicAgent from src.utils.memory_manager import PostgresMemoryManager from app.enhanced_routes import router as enhanced_router from app.schemas import SessionResponse, ChatMessage, ChatResponse, HistoryResponse app = FastAPI(title="Nebula AI Agent API") # Get the frontend URL from environment variables, fallback to local dev URLs frontend_url = os.environ.get("FRONTEND_URL", "http://localhost:3000") allowed_origins = [ frontend_url, "http://localhost:3000", "http://127.0.0.1:3000" ] app.add_middleware( CORSMiddleware, allow_origins=allowed_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) basic_agent = BasicAgent() memory_manager = PostgresMemoryManager() app.include_router(enhanced_router, prefix="/api/v2") @app.get("/") async def root(): return {"message": "Nebula AI Agent API is running!"} @app.post("/session/create", response_model=SessionResponse) async def create_session(request: Request): # 1. IP Extraction x_forwarded_for = request.headers.get("X-Forwarded-For") if x_forwarded_for: ip_address = x_forwarded_for.split(",")[0].strip() else: x_real_ip = request.headers.get("X-Real-IP") if x_real_ip: ip_address = x_real_ip else: ip_address = request.client.host if request.client else None # 2. Data Enrichment (IP Geolocation) location_data = None if ip_address and ip_address not in ("127.0.0.1", "::1", "localhost"): # Skip private ips usually try: async with httpx.AsyncClient(timeout=3.0) as client: resp = await client.get(f"http://ip-api.com/json/{ip_address}") if resp.status_code == 200: data = resp.json() if data.get("status") == "success": location_data = { "country": data.get("country"), "city": data.get("city"), "isp": data.get("isp"), "lat": data.get("lat"), "lon": data.get("lon"), } except Exception as e: print(f"Failed to fetch IP geolocation: {e}") # 3. Database Storage session_id = memory_manager.create_session(ip_address=ip_address, location_data=location_data) return SessionResponse(session_id=session_id) @app.post("/chat/{session_id}", response_model=ChatResponse) async def basic_chat(session_id: str, message: ChatMessage): response = basic_agent.generate_response(session_id, message.user_message) return ChatResponse(ai_response=response) @app.get("/history/{session_id}", response_model=HistoryResponse) async def get_history(session_id: str): history = memory_manager.get_history(session_id) return HistoryResponse(history=history)