from fastapi import FastAPI, HTTPException from fastapi.responses import StreamingResponse, HTMLResponse, Response from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel import uvicorn import asyncio import json from brain import Brain app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) brain: Brain | None = None BASE = "https://amogaddy-generai.hf.space" # ── Shared layout ────────────────────────────────────────────────────────────── def page(title: str, content: str, active: str = "") -> str: nav_items = [ ("/", "🏠", "Home"), ("/chat", "💬", "Chat"), ("/commands", "⚡", "Comandi"), ("/docs", "📖", "API Docs"), ] nav_html = "".join( f'{icon} {label}' for href, icon, label in nav_items ) return f"""
Assistente AI in italiano con memoria locale e ricerca web.
| Componente | Stato | Info |
|---|---|---|
| AI Brain | {status} | KB + Web search |
| Knowledge Base | Online | {kb} documenti in memoria |
| Ricerca Web | Chromium | Browser headless (Playwright) |
Fai una domanda alla AI — vedrai i passaggi in tempo reale.
Scegli PowerShell o CMD, copia il comando. Oppure scarica lo script completo.
{sections_html} """ return HTMLResponse(page("Comandi", content, "/commands")) # ── Script downloads ─────────────────────────────────────────────────────────── @app.get("/scripts/powershell") def script_ps(): script = f"""# GenerAI — Script PowerShell | .\generai.ps1 $BASE = "{BASE}" function Ask($d) {{ $r = Invoke-RestMethod -Uri "$BASE/ask" -Method POST -ContentType "application/json" -Body (@{{prompt=$d}}|ConvertTo-Json) Write-Host "`n[$($r.status)]" -ForegroundColor Cyan; Write-Host $r.result }} function AskStream($d) {{ curl -s -N -X POST "$BASE/ask/stream" -H "Content-Type: application/json" -d (@{{prompt=$d}}|ConvertTo-Json -Compress) }} function Stato {{ Invoke-RestMethod "$BASE/" | ConvertTo-Json }} function Feedback($p) {{ Invoke-RestMethod -Uri "$BASE/feedback?positive=$p" -Method POST | Out-Null Write-Host "Feedback inviato!" -ForegroundColor Green }} while ($true) {{ Write-Host "`n===== GENERAI =====" -ForegroundColor Magenta Write-Host "1. Domanda 2. Streaming 3. Stato 4/5. Feedback 0. Esci" switch (Read-Host "Scelta") {{ "1" {{ Ask (Read-Host "Domanda") }} "2" {{ AskStream (Read-Host "Domanda") }} "3" {{ Stato }} "4" {{ Feedback "true" }} "5" {{ Feedback "false" }} "0" {{ exit }} default {{ Write-Host "Scelta non valida" -ForegroundColor Red }} }} }} """ return Response(content=script, media_type="text/plain", headers={"Content-Disposition": "attachment; filename=generai.ps1"}) @app.get("/scripts/batch") def script_bat(): script = f"""@echo off chcp 65001 >nul set BASE={BASE} :menu echo. echo ===== GENERAI ===== echo 1.Domanda 2.Streaming 3.Stato 0.Esci set /p s=Scelta: if "%s%"=="1" (set /p d=Domanda: & curl -s -X POST "%BASE%/ask" -H "Content-Type: application/json" -d "{{\\"prompt\\":\\"%d%\\"}}" & echo.) & goto menu if "%s%"=="2" (set /p d=Domanda: & curl -N -X POST "%BASE%/ask/stream" -H "Content-Type: application/json" -d "{{\\"prompt\\":\\"%d%\\"}}" & echo.) & goto menu if "%s%"=="3" (curl -s "%BASE%/" & echo.) & goto menu if "%s%"=="0" exit /b goto menu """ return Response(content=script, media_type="text/plain", headers={"Content-Disposition": "attachment; filename=generai.bat"}) # ── API endpoints ────────────────────────────────────────────────────────────── class AskRequest(BaseModel): prompt: str @app.post("/ask") async def ask(req: AskRequest): if not brain: raise HTTPException(status_code=503, detail="Brain non ancora pronto") answer, status = await brain.ask(req.prompt) return {"result": answer, "status": status} @app.post("/ask/stream") async def ask_stream(req: AskRequest): if not brain: raise HTTPException(status_code=503, detail="Brain non ancora pronto") async def generate(): queue: asyncio.Queue = asyncio.Queue() async def on_status(msg: str): await queue.put(("status", msg)) async def run(): answer, status = await brain.ask(req.prompt, on_status=on_status) await queue.put(("result", answer, status)) task = asyncio.create_task(run()) while True: item = await queue.get() if item[0] == "status": yield f"data: {json.dumps({'type':'status','message':item[1]})}\n\n" elif item[0] == "result": yield f"data: {json.dumps({'type':'result','message':item[1],'status':item[2]})}\n\n" break await task return StreamingResponse(generate(), media_type="text/event-stream") @app.post("/feedback") def feedback(positive: bool): if brain: brain.give_feedback(positive) return {"ok": True} @app.on_event("startup") async def startup(): global brain brain = Brain() if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)