import os from datetime import datetime from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse from pydantic import BaseModel from typing import Optional, List from openai import OpenAI # ── App Setup ────────────────────────────────────────────────────────────── app = FastAPI(title="HERMES AGENT", version="1.0.0") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) # ── Config ───────────────────────────────────────────────────────────────── NVIDIA_API_KEY = os.getenv("OPENAI_API_KEY", "") SUPABASE_URL = os.getenv("SUPABASE_URL", "") SUPABASE_KEY = os.getenv("SUPABASE_KEY", "") HERMES_NAME = os.getenv("HERMES_NAME", "HERMES") NVIDIA_MODEL = os.getenv("NVIDIA_MODEL", "meta/llama-3.1-70b-instruct") HERMES_SYSTEM_PROMPT = os.getenv( "HERMES_SYSTEM_PROMPT", "Eres HERMES, un agente de inteligencia artificial avanzado, leal y preciso. " "Tienes memoria persistente. Respondes en el mismo idioma que el usuario." ) # ── NVIDIA NIM Client (OpenAI-compatible) ────────────────────────────────── client: Optional[OpenAI] = None if NVIDIA_API_KEY: client = OpenAI( base_url="https://integrate.api.nvidia.com/v1", api_key=NVIDIA_API_KEY ) print(f"[HERMES] NVIDIA NIM client initialized. Model: {NVIDIA_MODEL}") else: print("[HERMES] WARNING: OPENAI_API_KEY not set!") # ── Supabase memory ──────────────────────────────────────────────────────── supabase = None if SUPABASE_URL and SUPABASE_KEY: try: from supabase import create_client supabase = create_client(SUPABASE_URL, SUPABASE_KEY) print("[HERMES] Supabase connected.") except Exception as e: print(f"[HERMES] Supabase error: {e}") # In-memory fallback when Supabase not configured _mem_fallback: dict = {} def get_memory(session_id: str, limit: int = 20) -> List[dict]: if supabase: try: r = (supabase.table("hermes_memory") .select("role,content") .eq("session_id", session_id) .order("created_at", desc=False) .limit(limit) .execute()) return r.data or [] except Exception as e: print(f"[Memory] read error: {e}") return _mem_fallback.get(session_id, [])[-limit:] def save_memory(session_id: str, role: str, content: str, user_id: str = "anon"): if supabase: try: supabase.table("hermes_memory").insert({ "session_id": session_id, "user_id": user_id, "role": role, "content": content, "created_at": datetime.utcnow().isoformat() }).execute() return except Exception as e: print(f"[Memory] save error: {e}") # fallback if session_id not in _mem_fallback: _mem_fallback[session_id] = [] _mem_fallback[session_id].append({"role": role, "content": content}) # ── Models ───────────────────────────────────────────────────────────────── class ChatRequest(BaseModel): message: str session_id: str = "default" user_id: str = "anonymous" class ChatResponse(BaseModel): reply: str session_id: str timestamp: str model: str # ── Routes ───────────────────────────────────────────────────────────────── @app.get("/", response_class=HTMLResponse) async def root(): return """