The /registry/agents endpoint was 500 on every call because AgentRegistry.get_all() is async but was called without await. Also aligns get_all() dict keys (name, domain) with what the router reads. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
3.4 KiB
Python
99 lines
3.4 KiB
Python
from __future__ import annotations
|
|
import logging
|
|
from typing import Optional
|
|
|
|
from fastapi import APIRouter, HTTPException, status
|
|
from pydantic import BaseModel
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter(prefix='/registry', tags=['registry'])
|
|
|
|
|
|
class AgentInfo(BaseModel):
|
|
name: str
|
|
domain: str
|
|
active: bool
|
|
backend: str = 'ollama'
|
|
last_seen: Optional[str] = None
|
|
|
|
|
|
class BackendOverride(BaseModel):
|
|
agent_name: str
|
|
backend: str # ollama | claude
|
|
set_by: str
|
|
note: Optional[str] = None
|
|
|
|
|
|
@router.get('/agents', response_model=list[AgentInfo])
|
|
async def list_agents():
|
|
from ..app_state import get_agent_registry, get_llm_router
|
|
registry = get_agent_registry()
|
|
llm_router = get_llm_router()
|
|
if registry is None:
|
|
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail='Registry not ready')
|
|
agents = await registry.get_all()
|
|
result = []
|
|
for agent in agents:
|
|
backend = 'ollama'
|
|
if llm_router:
|
|
try:
|
|
backend = await llm_router.get_backend(agent['name'])
|
|
except Exception:
|
|
pass
|
|
result.append(AgentInfo(
|
|
name=agent['name'],
|
|
domain=agent.get('domain', ''),
|
|
active=agent.get('active', True),
|
|
backend=backend,
|
|
last_seen=agent.get('last_seen'),
|
|
))
|
|
return result
|
|
|
|
|
|
@router.post('/sync', status_code=status.HTTP_200_OK)
|
|
async def sync_registry():
|
|
from ..app_state import get_agent_registry
|
|
registry = get_agent_registry()
|
|
if registry is None:
|
|
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail='Registry not ready')
|
|
try:
|
|
count = await registry.sync()
|
|
return {'synced': count}
|
|
except Exception as exc:
|
|
logger.error('registry sync failed: %s', exc)
|
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc))
|
|
|
|
|
|
@router.post('/backend', status_code=status.HTTP_200_OK)
|
|
async def set_backend_override(req: BackendOverride):
|
|
from ..app_state import get_llm_router
|
|
llm_router = get_llm_router()
|
|
if llm_router is None:
|
|
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail='LLM router not ready')
|
|
if req.backend not in ('ollama', 'claude'):
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='backend must be ollama or claude')
|
|
try:
|
|
await llm_router.set_backend_override(
|
|
caller=req.agent_name,
|
|
backend=req.backend,
|
|
set_by=req.set_by,
|
|
note=req.note,
|
|
)
|
|
return {'agent': req.agent_name, 'backend': req.backend}
|
|
except Exception as exc:
|
|
logger.error('set_backend_override failed: %s', exc)
|
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc))
|
|
|
|
|
|
@router.delete('/backend/{agent_name}', status_code=status.HTTP_200_OK)
|
|
async def reset_backend_override(agent_name: str):
|
|
from ..app_state import get_llm_router
|
|
llm_router = get_llm_router()
|
|
if llm_router is None:
|
|
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail='LLM router not ready')
|
|
try:
|
|
await llm_router.reset_backend_override(caller=agent_name)
|
|
return {'agent': agent_name, 'reset': True}
|
|
except Exception as exc:
|
|
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc))
|