Spaces:
Running
Running
| 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] = {} | |
| async def list_workers(): | |
| return list(WORKERS_REGISTRY.values()) | |
| 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} | |
| 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 | |
| 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} | |