""" OPC Agents Router """ from fastapi import APIRouter, Depends, HTTPException, Request from pydantic import BaseModel from db import opc_db from rbac import User, require_admin router = APIRouter() class AgentUpdate(BaseModel): name: str | None = None description: str | None = None system_prompt: str | None = None enabled: bool | None = None class ExecutionApproval(BaseModel): approved: bool feedback: str | None = None @router.get("/agents") async def list_agents( request: Request, enabled_only: bool = True, ): """List all agents""" user: User = request.state.user agents = await opc_db.get_agents(enabled_only=enabled_only) return {"items": agents} @router.get("/agents/{agent_id}") async def get_agent( agent_id: str, request: Request, ): """Get agent details""" user: User = request.state.user agent = await opc_db.get_agent(agent_id) if not agent: raise HTTPException(status_code=404, detail="Agent not found") return agent @router.put("/agents/{agent_id}", dependencies=[Depends(require_admin())]) async def update_agent( agent_id: str, updates: AgentUpdate, request: Request, ): """Update agent configuration (admin only)""" user: User = request.state.user try: agent = await opc_db.update_agent_config( agent_id=agent_id, name=updates.name, description=updates.description, system_prompt=updates.system_prompt, enabled=updates.enabled, ) return agent except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) @router.post("/agents/{agent_id}/execute") async def trigger_agent( agent_id: str, task_id: int, request: Request, ): """Manually trigger agent execution""" user: User = request.state.user execution = await opc_db.create_agent_execution(task_id=task_id, agent_id=agent_id, actor=user.username) return execution @router.get("/executions") async def list_executions( request: Request, task_id: int | None = None, agent_id: str | None = None, status: str | None = None, limit: int = 50, ): """List agent executions""" user: User = request.state.user executions = await opc_db.get_agent_executions(task_id=task_id, agent_id=agent_id, status=status, limit=limit) return {"items": executions} @router.get("/executions/{execution_id}") async def get_execution( execution_id: int, request: Request, ): """Get execution details""" user: User = request.state.user execution = await opc_db.get_agent_execution(execution_id) if not execution: raise HTTPException(status_code=404, detail="Execution not found") return execution @router.post("/executions/{execution_id}/approve") async def approve_execution( execution_id: int, approval: ExecutionApproval, request: Request, ): """Approve or reject agent execution (for CxO level actions)""" user: User = request.state.user try: execution = await opc_db.approve_agent_execution( execution_id=execution_id, approved=approval.approved, approved_by=user.username, feedback=approval.feedback ) return execution except ValueError as e: raise HTTPException(status_code=404, detail=str(e))