| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- from fastapi import APIRouter, Depends, HTTPException, Query
- from sqlalchemy import text
- from sqlalchemy.orm import Session
- from core_domain import ServiceHealth
- from app.application.services import AgentApplicationService, build_agent_application_service
- from app.bootstrap.settings import AgentServiceSettings
- from app.db.session import get_db
- from app.schemas.agent import (
- AgentCreateRequest,
- AgentResponse,
- AgentRunCreateRequest,
- AgentRunExecuteRequest,
- AgentRunExecuteResponse,
- AgentRunResponse,
- AgentRunStatusUpdateRequest,
- AgentStatusUpdateRequest,
- AgentToolInvocationResponse,
- AgentWorkerExecuteNextRequest,
- AgentWorkerExecuteNextResponse,
- AgentVersionCreateRequest,
- AgentVersionResponse,
- )
- router = APIRouter()
- def get_agent_service_settings() -> AgentServiceSettings:
- return AgentServiceSettings()
- def get_agent_application_service(
- db: Session = Depends(get_db),
- settings: AgentServiceSettings = Depends(get_agent_service_settings),
- ) -> AgentApplicationService:
- return build_agent_application_service(db=db, settings=settings)
- @router.get("/health", response_model=ServiceHealth)
- def health_check(db: Session = Depends(get_db)) -> ServiceHealth:
- db.execute(text("SELECT 1"))
- return ServiceHealth(service="agent-service", status="ok", database="ok")
- @router.post("", response_model=AgentResponse)
- def create_agent(
- payload: AgentCreateRequest,
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentResponse:
- entity = service.create_agent(payload)
- return AgentResponse.from_entity(entity)
- @router.get("", response_model=list[AgentResponse])
- def list_agents(
- tenant_id: str = Query(...),
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> list[AgentResponse]:
- return [AgentResponse.from_entity(item) for item in service.list_agents(tenant_id=tenant_id)]
- @router.patch("/{agent_id}/status", response_model=AgentResponse)
- def update_agent_status(
- agent_id: str,
- payload: AgentStatusUpdateRequest,
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentResponse:
- entity = service.update_agent_status(agent_id=agent_id, payload=payload)
- if entity is None:
- raise HTTPException(status_code=404, detail=f"agent not found: {agent_id}")
- return AgentResponse.from_entity(entity)
- @router.post("/versions", response_model=AgentVersionResponse)
- def create_agent_version(
- payload: AgentVersionCreateRequest,
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentVersionResponse:
- try:
- entity = service.create_agent_version(payload)
- except ValueError as exc:
- raise HTTPException(status_code=422, detail=str(exc)) from exc
- return AgentVersionResponse.from_entity(entity)
- @router.get("/versions", response_model=list[AgentVersionResponse])
- def list_agent_versions(
- tenant_id: str = Query(...),
- agent_id: str = Query(...),
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> list[AgentVersionResponse]:
- return [
- AgentVersionResponse.from_entity(item)
- for item in service.list_agent_versions(tenant_id=tenant_id, agent_id=agent_id)
- ]
- @router.post("/runs", response_model=AgentRunResponse)
- def create_agent_run(
- payload: AgentRunCreateRequest,
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentRunResponse:
- try:
- entity = service.create_agent_run(payload)
- except ValueError as exc:
- raise HTTPException(status_code=422, detail=str(exc)) from exc
- return AgentRunResponse.from_entity(entity)
- @router.get("/runs", response_model=list[AgentRunResponse])
- def list_agent_runs(
- tenant_id: str = Query(...),
- agent_id: str | None = Query(default=None),
- session_id: str | None = Query(default=None),
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> list[AgentRunResponse]:
- return [
- AgentRunResponse.from_entity(item)
- for item in service.list_agent_runs(
- tenant_id=tenant_id,
- agent_id=agent_id,
- session_id=session_id,
- )
- ]
- @router.get(
- "/runs/{agent_run_id}/tool-invocations",
- response_model=list[AgentToolInvocationResponse],
- )
- def list_agent_tool_invocations(
- agent_run_id: str,
- tenant_id: str = Query(...),
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> list[AgentToolInvocationResponse]:
- return [
- AgentToolInvocationResponse.from_entity(item)
- for item in service.list_agent_tool_invocations(
- tenant_id=tenant_id,
- agent_run_id=agent_run_id,
- )
- ]
- @router.post("/runs/{agent_run_id}/status", response_model=AgentRunResponse)
- def update_agent_run_status(
- agent_run_id: str,
- payload: AgentRunStatusUpdateRequest,
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentRunResponse:
- entity = service.update_agent_run_status(agent_run_id=agent_run_id, payload=payload)
- if entity is None:
- raise HTTPException(status_code=404, detail=f"agent_run not found: {agent_run_id}")
- return AgentRunResponse.from_entity(entity)
- @router.post("/runs/{agent_run_id}/execute", response_model=AgentRunExecuteResponse)
- def execute_agent_run(
- agent_run_id: str,
- payload: AgentRunExecuteRequest,
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentRunExecuteResponse:
- entity = service.execute_agent_run(agent_run_id=agent_run_id, payload=payload)
- if entity is None:
- raise HTTPException(status_code=404, detail=f"agent_run not found: {agent_run_id}")
- output_json = entity.output_json or {}
- model_value = output_json.get("model")
- dry_run_value = output_json.get("dry_run")
- return AgentRunExecuteResponse(
- run=AgentRunResponse.from_entity(entity),
- model=model_value if isinstance(model_value, str) else None,
- dry_run=dry_run_value if isinstance(dry_run_value, bool) else False,
- )
- @router.post("/workers/execute-next", response_model=AgentWorkerExecuteNextResponse)
- def execute_next_worker_task(
- payload: AgentWorkerExecuteNextRequest,
- settings: AgentServiceSettings = Depends(get_agent_service_settings),
- service: AgentApplicationService = Depends(get_agent_application_service),
- ) -> AgentWorkerExecuteNextResponse:
- result = service.execute_next_claimed_agent_run(
- worker_key=payload.worker_key,
- lease_seconds=payload.lease_seconds or settings.worker_lease_seconds,
- dry_run=payload.dry_run if payload.dry_run is not None else settings.worker_dry_run,
- )
- if result is None:
- raise HTTPException(status_code=404, detail="queued agent_run not found")
- entity, released_lease_count = result
- output_json = entity.output_json or {}
- model_value = output_json.get("model")
- dry_run_value = output_json.get("dry_run")
- return AgentWorkerExecuteNextResponse(
- run=AgentRunResponse.from_entity(entity),
- model=model_value if isinstance(model_value, str) else None,
- dry_run=dry_run_value if isinstance(dry_run_value, bool) else False,
- released_lease_count=released_lease_count,
- )
|