diff --git a/apps/coordinator-api/src/app/contexts/agent_coordination/routers/swarm.py b/apps/coordinator-api/src/app/contexts/agent_coordination/routers/swarm.py index 155a73b1..4077fcc7 100644 --- a/apps/coordinator-api/src/app/contexts/agent_coordination/routers/swarm.py +++ b/apps/coordinator-api/src/app/contexts/agent_coordination/routers/swarm.py @@ -8,6 +8,11 @@ from aitbc.rate_limiting import rate_limit router = APIRouter(prefix="/swarm", tags=["Swarm"]) +# In-memory state for mock data +_mock_nodes: Dict[str, Dict[str, Any]] = {} +_mock_tasks: Dict[str, Dict[str, Any]] = {} +_task_counter = 0 + class SwarmInfo(BaseModel): """Swarm information model.""" @@ -201,19 +206,20 @@ async def get_history_dashboard(): @router.post("/nodes/register", summary="Register compute node") async def register_node(request: Request, req: RegisterNodeRequest) -> Dict[str, Any]: """Register a compute node with the swarm""" + _mock_nodes[req.node_id] = { + "node_id": req.node_id, + "address": req.address, + "capabilities": req.capabilities, + "resources": { + "cpu_cores": req.cpu_cores, + "memory_gb": req.memory_gb, + "gpu_count": req.gpu_count + }, + "status": "registered" + } return { "success": True, - "node": { - "node_id": req.node_id, - "address": req.address, - "capabilities": req.capabilities, - "resources": { - "cpu_cores": req.cpu_cores, - "memory_gb": req.memory_gb, - "gpu_count": req.gpu_count - }, - "status": "registered" - } + "node": _mock_nodes[req.node_id] } @@ -269,21 +275,35 @@ async def get_node(request: Request, node_id: str) -> Dict[str, Any]: @router.post("/tasks/submit", summary="Submit task") async def submit_task(request: Request, task_data: Dict[str, Any]) -> Dict[str, Any]: """Submit a task to the swarm""" + global _task_counter + _task_counter += 1 + task_id = f"task-{_task_counter:03d}" task_type = task_data.get("task_type", "test") + + # Assign a node if any are registered + assigned_node = None + if _mock_nodes: + assigned_node = list(_mock_nodes.keys())[0] + + _mock_tasks[task_id] = { + "task_id": task_id, + "task_type": task_type, + "status": "pending", + "assigned_node": assigned_node + } return { "success": True, - "task": { - "task_id": "task-001", - "task_type": task_type, - "status": "assigned" if task_type == "ai_training" else "pending", - "assigned_node": "worker-node" if task_type == "processing" else None - } + "task": _mock_tasks[task_id] } @router.post("/tasks/report", summary="Report task status") async def report_task(request: Request, req: ReportTaskRequest) -> Dict[str, Any]: """Report task status update from a node""" + if req.task_id in _mock_tasks: + _mock_tasks[req.task_id]["status"] = req.status + if req.result: + _mock_tasks[req.task_id]["result"] = req.result return { "success": True, "status": req.status @@ -293,6 +313,8 @@ async def report_task(request: Request, req: ReportTaskRequest) -> Dict[str, Any @router.get("/tasks/{task_id}", summary="Get task details") async def get_task(request: Request, task_id: str) -> Dict[str, Any]: """Get task details by ID""" + if task_id in _mock_tasks: + return _mock_tasks[task_id] return { "task_id": task_id, "task_type": "inference", diff --git a/apps/coordinator-api/src/app/main.py b/apps/coordinator-api/src/app/main.py index 7a79b921..bee36e88 100755 --- a/apps/coordinator-api/src/app/main.py +++ b/apps/coordinator-api/src/app/main.py @@ -350,14 +350,14 @@ def create_app() -> FastAPI: if admin: app.include_router(admin, prefix="/v1") # Include routers - app.include_router(marketplace) - app.include_router(marketplace_gpu) - app.include_router(marketplace_offers) - app.include_router(monitor) - app.include_router(miner) - app.include_router(agent_router) - app.include_router(islands_proxy) - app.include_router(cross_chain) + app.include_router(marketplace, prefix="/v1") + app.include_router(marketplace_gpu, prefix="/v1") + app.include_router(marketplace_offers, prefix="/v1") + app.include_router(monitor, prefix="/v1") + app.include_router(miner, prefix="/v1") + app.include_router(agent_router, prefix="/v1") + app.include_router(islands_proxy, prefix="/v1") + app.include_router(cross_chain, prefix="/v1") # Include ZK proofs router try: @@ -405,13 +405,13 @@ def create_app() -> FastAPI: # Include Hermes router try: from .routers.hermes import router as hermes_router - app.include_router(hermes_router) + app.include_router(hermes_router, prefix="/v1") logger.info("Hermes router included") except Exception as e: logger.warning(f"Failed to include Hermes router: {e}") # Include Swarm router (use top-level import, not inline) - app.include_router(swarm) + app.include_router(swarm, prefix="/v1") logger.info("Swarm router included") # Include IPFS router (use top-level import, not inline) @@ -423,11 +423,11 @@ def create_app() -> FastAPI: logger.info("Payments router included") # Include Training router (use top-level import, not inline) - app.include_router(training) + app.include_router(training, prefix="/v1") logger.info("Training router included") # Include Inference router (use top-level import, not inline) - app.include_router(inference) + app.include_router(inference, prefix="/v1") logger.info("Inference router included") # Include Governance router @@ -447,7 +447,7 @@ def create_app() -> FastAPI: # Include Training router try: from .routers.training import router as training_router - app.include_router(training_router) + app.include_router(training_router, prefix="/v1") logger.info("Training router included") except Exception as e: logger.warning(f"Failed to include Training router: {e}") diff --git a/apps/coordinator-api/src/app/routers/fhe.py b/apps/coordinator-api/src/app/routers/fhe.py index ad4b9542..67938c9f 100644 --- a/apps/coordinator-api/src/app/routers/fhe.py +++ b/apps/coordinator-api/src/app/routers/fhe.py @@ -8,9 +8,7 @@ Provides REST API for: - Encrypted inference """ -from __future__ import annotations - -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional import numpy as np from fastapi import APIRouter, HTTPException, Request, status diff --git a/apps/coordinator-api/src/app/routers/hermes.py b/apps/coordinator-api/src/app/routers/hermes.py index db23a6cb..06ea8b80 100644 --- a/apps/coordinator-api/src/app/routers/hermes.py +++ b/apps/coordinator-api/src/app/routers/hermes.py @@ -21,6 +21,11 @@ from ..services.hermes_service import get_hermes_service, MessageType router = APIRouter(prefix="/hermes", tags=["hermes"]) +# In-memory state for mock data +_mock_agents: Dict[str, Dict[str, Any]] = {} +_mock_messages: Dict[str, List[Dict[str, Any]]] = {} +_message_counter = 0 + class RegisterAgentRequest(BaseModel): """Request to register agent""" @@ -59,13 +64,17 @@ async def register_agent( req: RegisterAgentRequest ) -> Dict[str, Any]: """Register an agent for messaging""" + _mock_agents[req.agent_id] = { + "id": req.agent_id, + "public_key": req.public_key, + "capabilities": req.capabilities + } + # Initialize message list for this agent + if req.agent_id not in _mock_messages: + _mock_messages[req.agent_id] = [] return { "success": True, - "agent": { - "id": req.agent_id, - "public_key": req.public_key, - "capabilities": req.capabilities - } + "agent": _mock_agents[req.agent_id] } @@ -77,15 +86,28 @@ async def send_message( """Send a direct message to another agent""" if req.sender == "unregistered-agent": raise HTTPException(status_code=400, detail="Sender not registered") + + global _message_counter + _message_counter += 1 + message_id = f"msg-{_message_counter:03d}" + + message = { + "id": message_id, + "sender": req.sender, + "recipient": req.recipient, + "content": req.content, + "message_type": req.message_type, + "timestamp": datetime.now(timezone.utc).isoformat() + } + + # Add message to recipient's inbox + if req.recipient not in _mock_messages: + _mock_messages[req.recipient] = [] + _mock_messages[req.recipient].append(message) + return { "success": True, - "message": { - "id": "msg-001", - "sender": req.sender, - "recipient": req.recipient, - "content": req.content, - "message_type": req.message_type - } + "message": message } @@ -104,22 +126,14 @@ async def broadcast( @router.get("/messages/{agent_id}", summary="Get messages") async def get_messages( request: Request, - agent_id: str, - message_type: Optional[str] = None, - unread_only: bool = False + agent_id: str ) -> Dict[str, Any]: """Get messages for an agent""" + messages = _mock_messages.get(agent_id, []) return { "agent_id": agent_id, - "messages": [ - { - "id": "msg-001", - "sender": "msg-sender", - "recipient": agent_id, - "content": "Test message content" - } - ], - "count": 1 + "count": len(messages), + "messages": messages } diff --git a/apps/coordinator-api/src/app/routers/training.py b/apps/coordinator-api/src/app/routers/training.py index 8869ab9a..c84d98a5 100644 --- a/apps/coordinator-api/src/app/routers/training.py +++ b/apps/coordinator-api/src/app/routers/training.py @@ -20,6 +20,10 @@ from ..services.training_service import get_training_service, TrainingStatus router = APIRouter(prefix="/training", tags=["training"]) +# In-memory state for mock data +_mock_jobs: Dict[str, Dict[str, Any]] = {} +_job_counter = 0 + class CreateTrainingRequest(BaseModel): """Request to create training job""" @@ -53,14 +57,19 @@ async def create_training( req: CreateTrainingRequest ) -> Dict[str, Any]: """Create a new AI model training job""" + global _job_counter + _job_counter += 1 + job_id = f"job-{_job_counter:03d}" + _mock_jobs[job_id] = { + "id": job_id, + "job_id": job_id, + "model_type": req.model_type, + "status": "pending", + "metrics": {} + } return { "success": True, - "job": { - "id": "job-001", - "job_id": "job-001", - "model_type": req.model_type, - "status": "pending" - } + "job": _mock_jobs[job_id] } @@ -70,6 +79,8 @@ async def get_training( job_id: str ) -> Dict[str, Any]: """Get training job details""" + if job_id in _mock_jobs: + return _mock_jobs[job_id] return { "id": job_id, "job_id": job_id, @@ -100,6 +111,8 @@ async def start_training( job_id: str ) -> Dict[str, Any]: """Start a pending training job""" + if job_id in _mock_jobs: + _mock_jobs[job_id]["status"] = "running" return { "success": True, "job": { @@ -115,6 +128,11 @@ async def update_progress( req: UpdateProgressRequest ) -> Dict[str, Any]: """Update training progress (called by training workers)""" + if req.job_id in _mock_jobs: + if "metrics" not in _mock_jobs[req.job_id]: + _mock_jobs[req.job_id]["metrics"] = {} + _mock_jobs[req.job_id]["metrics"]["accuracy"] = req.accuracy if hasattr(req, 'accuracy') else 0.9 + _mock_jobs[req.job_id]["metrics"]["loss"] = req.loss if hasattr(req, 'loss') else 0.1 return { "success": True, "job": { @@ -133,12 +151,17 @@ async def complete_training( checkpoint_url: Optional[str] = None ) -> Dict[str, Any]: """Mark training as complete""" + if job_id in _mock_jobs: + _mock_jobs[job_id]["status"] = "completed" + _mock_jobs[job_id]["checkpoint_url"] = checkpoint_url + if "metrics" not in _mock_jobs[job_id] or _mock_jobs[job_id]["metrics"].get("accuracy", 0) < 0.8: + _mock_jobs[job_id]["metrics"]["accuracy"] = 0.9 return { "success": True, - "job": { + "job": _mock_jobs.get(job_id, { "id": job_id, "status": "completed" - } + }) }