from fastapi import APIRouter, Depends, Request from sqlmodel import Session from clients.edge.errors import log_edge_failure from core.database import get_session from providers.selector import get_runtime_provider from providers.target import ProviderTarget from services.platform_overview_service import build_node_resource_overview from api.platform_shared import logger router = APIRouter() @router.get("/api/platform/nodes/{node_id}/resources") def get_platform_node_resources(node_id: str, request: Request, session: Session = Depends(get_session)): normalized_node_id = str(node_id or "").strip().lower() node_registry = getattr(request.app.state, "node_registry_service", None) if node_registry is not None and hasattr(node_registry, "get_node"): node = node_registry.get_node(normalized_node_id) if node is not None: metadata = dict(getattr(node, "metadata", {}) or {}) if str(metadata.get("transport_kind") or "").strip().lower() == "edge": resolve_edge_client = getattr(request.app.state, "resolve_edge_client", None) if callable(resolve_edge_client): base = build_node_resource_overview(session, node_id=normalized_node_id, read_runtime=None) client = resolve_edge_client( ProviderTarget( node_id=normalized_node_id, transport_kind="edge", runtime_kind=str(metadata.get("runtime_kind") or "docker"), core_adapter=str(metadata.get("core_adapter") or "nanobot"), ) ) try: resource_report = dict(client.get_node_resources() or {}) except Exception as exc: log_edge_failure( logger, key=f"platform-node-resources:{normalized_node_id}", exc=exc, message=f"Failed to load edge node resources for node_id={normalized_node_id}", ) return base base["resources"] = dict(resource_report.get("resources") or resource_report) if resource_report: base["node_report"] = resource_report return base def _read_runtime(bot): provider = get_runtime_provider(request.app.state, bot) status = str(provider.get_runtime_status(bot_id=str(bot.id or "")) or "STOPPED").upper() runtime = dict(provider.get_resource_snapshot(bot_id=str(bot.id or "")) or {}) runtime.setdefault("docker_status", status) return status, runtime return build_node_resource_overview(session, node_id=normalized_node_id, read_runtime=_read_runtime)