Spaces:
Sleeping
Sleeping
File size: 6,184 Bytes
049b8a8 30b5ee2 049b8a8 29beabb 049b8a8 30b5ee2 29beabb 30b5ee2 29beabb 30b5ee2 29beabb 30b5ee2 29beabb 049b8a8 30b5ee2 049b8a8 30b5ee2 049b8a8 30b5ee2 049b8a8 3c8750c 049b8a8 3c8750c 049b8a8 30b5ee2 049b8a8 30b5ee2 049b8a8 30b5ee2 049b8a8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from pathlib import Path
from datetime import datetime
from agents.manager import plan_mission
from agents.specialized import run_specialized_agent
from core.storage import save_mission, load_recent_missions
app = FastAPI(title="Mission Control Aetheris")
# βββββββββββββββββββββββββββββ
# STATIC
# βββββββββββββββββββββββββββββ
templates_dir = Path("templates")
docs_dir = Path("data/docs")
if docs_dir.exists():
app.mount("/docs", StaticFiles(directory=docs_dir), name="docs")
@app.get("/", response_class=HTMLResponse)
async def root():
return (templates_dir / "code_new.html").read_text(encoding="utf-8")
# βββββββββββββββββββββββββββββ
# HEALTH
# βββββββββββββββββββββββββββββ
@app.get("/health")
async def health():
return {"status": "ok"}
# βββββββββββββββββββββββββββββ
# HISTORY
# βββββββββββββββββββββββββββββ
@app.get("/api/history")
async def get_history():
try:
missions = load_recent_missions(limit=100)
return {"missions": missions}
except Exception as e:
return JSONResponse({"error": str(e)}, status_code=500)
# βββββββββββββββββββββββββββββ
# DIAGNOSTICS
# βββββββββββββββββββββββββββββ
@app.get("/api/diagnostics")
async def diagnostics():
try:
import psutil, time
cpu_percent = psutil.cpu_percent(interval=0.3)
cpu_count = psutil.cpu_count()
ram = psutil.virtual_memory()
ram_total_gb = round(ram.total / (1024**3), 2)
ram_used_gb = round(ram.used / (1024**3), 2)
ram_percent = ram.percent
disk = psutil.disk_usage("/")
disk_total_gb = round(disk.total / (1024**3), 2)
disk_used_gb = round(disk.used / (1024**3), 2)
disk_percent = disk.percent
net1 = psutil.net_io_counters()
time.sleep(0.5)
net2 = psutil.net_io_counters()
net_in_kb = round((net2.bytes_recv - net1.bytes_recv) / 512, 2)
net_out_kb = round((net2.bytes_sent - net1.bytes_sent) / 512, 2)
net_in_total_mb = round(net2.bytes_recv / (1024**2), 2)
net_out_total_mb = round(net2.bytes_sent / (1024**2), 2)
return {
"timestamp": datetime.now().isoformat(),
"cpu": {"percent": cpu_percent, "cores": cpu_count},
"ram": {"percent": ram_percent, "used_gb": ram_used_gb, "total_gb": ram_total_gb},
"disk": {"percent": disk_percent, "used_gb": disk_used_gb, "total_gb": disk_total_gb},
"network": {
"in_kb_s": net_in_kb, "out_kb_s": net_out_kb,
"in_total_mb": net_in_total_mb, "out_total_mb": net_out_total_mb,
}
}
except Exception as e:
return JSONResponse({"error": str(e)}, status_code=500)
# βββββββββββββββββββββββββββββ
# MANAGER (CHAT)
# βββββββββββββββββββββββββββββ
@app.post("/api/manager")
async def manager_only(request: Request):
data = await request.json()
task = data.get("task", "").strip()
if not task:
return JSONResponse({"error": "No task"}, status_code=400)
plan = await plan_mission(task)
return {
"response": plan.get("reasoning"),
"delegate": plan.get("delegate"),
"raw": plan.get("raw"),
"provider": "HuggingFace Router",
"model": "Qwen/Qwen2.5-7B-Instruct"
}
# βββββββββββββββββββββββββββββ
# MISIΓN COMPLETA
# βββββββββββββββββββββββββββββ
@app.post("/api/mission")
async def create_mission(request: Request):
data = await request.json()
task = data.get("task", "").strip()
if not task:
return JSONResponse({"error": "No task provided"}, status_code=400)
started_at = datetime.now().isoformat()
plan = await plan_mission(task)
# ββ Ordenar pipeline: analyst siempre antes que writer ββββββββββββββββββ
delegates = plan.get("delegate", [])
PIPELINE_ORDER = ["analyst", "backend_dev", "frontend_dev", "writer", "image_agent"]
delegates = sorted(delegates, key=lambda k: PIPELINE_ORDER.index(k) if k in PIPELINE_ORDER else 99)
results = []
shared_context = {}
for agent_key in delegates:
result = await run_specialized_agent(agent_key, task, context=shared_context)
results.append(result)
if result.get("success"):
shared_context[agent_key] = result.get("response", "")
file_path = next((r["file_path"] for r in results if r.get("file_path")), None)
file_url = f"/docs/{file_path}" if file_path else None
# Serializar results para SQLite (quitar objetos no-JSON)
safe_results = []
for r in results:
safe_results.append({
"agent": r.get("agent"),
"success": r.get("success"),
"response": r.get("response", "")[:2000], # limitar tamaΓ±o
"file_path": r.get("file_path"),
"file_type": r.get("file_type"),
"image_urls": r.get("image_urls", []),
})
save_mission({
"task": task,
"started_at": started_at,
"ended_at": datetime.now().isoformat(),
"plan": plan,
"results": safe_results,
"doc_file": file_path,
"events": [],
})
return {
"success": True,
"task": task,
"plan": plan,
"results": results,
"file_url": file_url
} |