Terminal / api /marketplace.py
Baida-A
Initial clean deploy (Reverse Proxy removed)
28a08e7
Raw
History Blame
2.64 kB
from fastapi import APIRouter, Depends
from .auth_guard import require_role, AuthRole
from pydantic import BaseModel
from typing import List, Dict, Optional, Any
import time
router = APIRouter(prefix="/api/marketplace", tags=["marketplace"], dependencies=[Depends(require_role(AuthRole.MACHINE))])
class WorkerCapability(BaseModel):
id: str
name: str
version: str = "1.0.0"
description: Optional[str] = None
status: str = "online"
last_seen: int = 0
# SLA & Metrics
cost: float = 0.0 # Costo per operazione o unitario
latency: float = 0.0 # Latenza media in ms
region: str = "global" # Regione geografica
gpu: bool = False # Disponibilità GPU
priority: int = 10 # Priorità (più basso = più prioritario)
# Lista di capacità supportate (es. ["browser", "shell", "vision"])
capabilities: List[str] = []
metadata: Dict[str, Any] = {}
WORKERS_REGISTRY: Dict[str, WorkerCapability] = {}
@router.get("/workers", response_model=List[WorkerCapability])
async def list_workers():
return list(WORKERS_REGISTRY.values())
@router.post("/register")
async def register_worker(worker: WorkerCapability):
worker.last_seen = int(time.time())
WORKERS_REGISTRY[worker.id] = worker
return {"status": "registered", "id": worker.id, "capabilities": worker.capabilities}
@router.get("/capabilities")
async def get_all_capabilities():
"""Ritorna l'elenco consolidato delle capacità disponibili da tutti i worker attivi."""
caps = {}
now = int(time.time())
for w in WORKERS_REGISTRY.values():
if now - w.last_seen < 300: # Worker attivo negli ultimi 5 minuti
for cap in w.capabilities:
if cap not in caps:
caps[cap] = []
caps[cap].append({
"worker_id": w.id,
"version": w.version,
"cost": w.cost,
"latency": w.latency,
"region": w.region
})
return caps
@router.post("/resolve")
async def resolve_capability(capability: str, constraints: Optional[Dict[str, Any]] = None):
"""
ARCH-E3.2: Capability Resolver
Endpoint per risolvere una capability in un Worker specifico.
"""
from .resolver import resolver, ResolverConstraints
c = ResolverConstraints(**constraints) if constraints else None
worker = await resolver.resolve(capability, c)
if not worker:
return {"status": "error", "message": f"No worker found for capability: {capability}"}
return {"status": "resolved", "worker": worker}