routes.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. from fastapi import APIRouter, Depends, HTTPException, Query
  2. from sqlalchemy import text
  3. from sqlalchemy.orm import Session
  4. from core_domain import ServiceHealth
  5. from app.application.services import AgentApplicationService
  6. from app.bootstrap.settings import AgentServiceSettings
  7. from app.db.session import get_db
  8. from app.domain.repositories import (
  9. AgentDefinitionRepository,
  10. AgentRunRepository,
  11. AgentVersionRepository,
  12. )
  13. from app.infrastructure.model_gateway_client import ModelGatewayClient
  14. from app.schemas.agent import (
  15. AgentCreateRequest,
  16. AgentResponse,
  17. AgentRunCreateRequest,
  18. AgentRunExecuteRequest,
  19. AgentRunExecuteResponse,
  20. AgentRunResponse,
  21. AgentRunStatusUpdateRequest,
  22. AgentStatusUpdateRequest,
  23. AgentVersionCreateRequest,
  24. AgentVersionResponse,
  25. )
  26. router = APIRouter()
  27. def get_agent_service_settings() -> AgentServiceSettings:
  28. return AgentServiceSettings()
  29. def get_agent_application_service(
  30. db: Session = Depends(get_db),
  31. settings: AgentServiceSettings = Depends(get_agent_service_settings),
  32. ) -> AgentApplicationService:
  33. return AgentApplicationService(
  34. agent_repository=AgentDefinitionRepository(db),
  35. agent_version_repository=AgentVersionRepository(db),
  36. agent_run_repository=AgentRunRepository(db),
  37. model_gateway_client=ModelGatewayClient(
  38. base_url=settings.model_gateway_service_url,
  39. timeout_seconds=settings.model_gateway_timeout_seconds,
  40. ),
  41. )
  42. @router.get("/health", response_model=ServiceHealth)
  43. def health_check(db: Session = Depends(get_db)) -> ServiceHealth:
  44. db.execute(text("SELECT 1"))
  45. return ServiceHealth(service="agent-service", status="ok", database="ok")
  46. @router.post("", response_model=AgentResponse)
  47. def create_agent(
  48. payload: AgentCreateRequest,
  49. service: AgentApplicationService = Depends(get_agent_application_service),
  50. ) -> AgentResponse:
  51. entity = service.create_agent(payload)
  52. return AgentResponse.from_entity(entity)
  53. @router.get("", response_model=list[AgentResponse])
  54. def list_agents(
  55. tenant_id: str = Query(...),
  56. service: AgentApplicationService = Depends(get_agent_application_service),
  57. ) -> list[AgentResponse]:
  58. return [AgentResponse.from_entity(item) for item in service.list_agents(tenant_id=tenant_id)]
  59. @router.patch("/{agent_id}/status", response_model=AgentResponse)
  60. def update_agent_status(
  61. agent_id: str,
  62. payload: AgentStatusUpdateRequest,
  63. service: AgentApplicationService = Depends(get_agent_application_service),
  64. ) -> AgentResponse:
  65. entity = service.update_agent_status(agent_id=agent_id, payload=payload)
  66. if entity is None:
  67. raise HTTPException(status_code=404, detail=f"agent not found: {agent_id}")
  68. return AgentResponse.from_entity(entity)
  69. @router.post("/versions", response_model=AgentVersionResponse)
  70. def create_agent_version(
  71. payload: AgentVersionCreateRequest,
  72. service: AgentApplicationService = Depends(get_agent_application_service),
  73. ) -> AgentVersionResponse:
  74. try:
  75. entity = service.create_agent_version(payload)
  76. except ValueError as exc:
  77. raise HTTPException(status_code=422, detail=str(exc)) from exc
  78. return AgentVersionResponse.from_entity(entity)
  79. @router.get("/versions", response_model=list[AgentVersionResponse])
  80. def list_agent_versions(
  81. tenant_id: str = Query(...),
  82. agent_id: str = Query(...),
  83. service: AgentApplicationService = Depends(get_agent_application_service),
  84. ) -> list[AgentVersionResponse]:
  85. return [
  86. AgentVersionResponse.from_entity(item)
  87. for item in service.list_agent_versions(tenant_id=tenant_id, agent_id=agent_id)
  88. ]
  89. @router.post("/runs", response_model=AgentRunResponse)
  90. def create_agent_run(
  91. payload: AgentRunCreateRequest,
  92. service: AgentApplicationService = Depends(get_agent_application_service),
  93. ) -> AgentRunResponse:
  94. try:
  95. entity = service.create_agent_run(payload)
  96. except ValueError as exc:
  97. raise HTTPException(status_code=422, detail=str(exc)) from exc
  98. return AgentRunResponse.from_entity(entity)
  99. @router.get("/runs", response_model=list[AgentRunResponse])
  100. def list_agent_runs(
  101. tenant_id: str = Query(...),
  102. agent_id: str | None = Query(default=None),
  103. session_id: str | None = Query(default=None),
  104. service: AgentApplicationService = Depends(get_agent_application_service),
  105. ) -> list[AgentRunResponse]:
  106. return [
  107. AgentRunResponse.from_entity(item)
  108. for item in service.list_agent_runs(
  109. tenant_id=tenant_id,
  110. agent_id=agent_id,
  111. session_id=session_id,
  112. )
  113. ]
  114. @router.post("/runs/{agent_run_id}/status", response_model=AgentRunResponse)
  115. def update_agent_run_status(
  116. agent_run_id: str,
  117. payload: AgentRunStatusUpdateRequest,
  118. service: AgentApplicationService = Depends(get_agent_application_service),
  119. ) -> AgentRunResponse:
  120. entity = service.update_agent_run_status(agent_run_id=agent_run_id, payload=payload)
  121. if entity is None:
  122. raise HTTPException(status_code=404, detail=f"agent_run not found: {agent_run_id}")
  123. return AgentRunResponse.from_entity(entity)
  124. @router.post("/runs/{agent_run_id}/execute", response_model=AgentRunExecuteResponse)
  125. def execute_agent_run(
  126. agent_run_id: str,
  127. payload: AgentRunExecuteRequest,
  128. service: AgentApplicationService = Depends(get_agent_application_service),
  129. ) -> AgentRunExecuteResponse:
  130. entity = service.execute_agent_run(agent_run_id=agent_run_id, payload=payload)
  131. if entity is None:
  132. raise HTTPException(status_code=404, detail=f"agent_run not found: {agent_run_id}")
  133. output_json = entity.output_json or {}
  134. model_value = output_json.get("model")
  135. dry_run_value = output_json.get("dry_run")
  136. return AgentRunExecuteResponse(
  137. run=AgentRunResponse.from_entity(entity),
  138. model=model_value if isinstance(model_value, str) else None,
  139. dry_run=dry_run_value if isinstance(dry_run_value, bool) else False,
  140. )