routes.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. from core_domain import ServiceHealth
  2. from core_dsl import EdgeDefinition, NodeDefinition, WorkflowDefinition
  3. from fastapi import APIRouter, Depends, HTTPException, Query
  4. from sqlalchemy import text
  5. from sqlalchemy.orm import Session
  6. from app.application.services import WorkflowApplicationService
  7. from app.db.session import get_db
  8. from app.domain.repositories import (
  9. AppDefinitionRepository,
  10. AppConfigRepository,
  11. WorkflowDefinitionRepository,
  12. WorkflowConfigRepository,
  13. )
  14. from app.schemas.app import (
  15. AppCreateRequest,
  16. AppListRequest,
  17. AppResponse,
  18. AppConfigCreateRequest,
  19. AppConfigListRequest,
  20. AppConfigResponse,
  21. )
  22. from app.schemas.workflow import (
  23. WorkflowCreateRequest,
  24. WorkflowDebuggerPlanRequest,
  25. WorkflowDebuggerPlanResponse,
  26. WorkflowDefinitionResponse,
  27. WorkflowDesignerValidateRequest,
  28. WorkflowDesignerValidateResponse,
  29. WorkflowListRequest,
  30. WorkflowConfigCreateRequest,
  31. WorkflowConfigDebuggerPlanRequest,
  32. WorkflowConfigDetailRequest,
  33. WorkflowConfigListRequest,
  34. WorkflowConfigResponse,
  35. )
  36. router = APIRouter()
  37. def get_workflow_application_service(db: Session = Depends(get_db)) -> WorkflowApplicationService:
  38. return WorkflowApplicationService(
  39. app_repository=AppDefinitionRepository(db),
  40. workflow_repository=WorkflowDefinitionRepository(db),
  41. app_config_repository=AppConfigRepository(db),
  42. workflow_config_repository=WorkflowConfigRepository(db))
  43. @router.get("/health", response_model=ServiceHealth)
  44. def health_check(db: Session = Depends(get_db)) -> ServiceHealth:
  45. db.execute(text("SELECT 1"))
  46. return ServiceHealth(service="workflow-service", status="ok", database="ok")
  47. @router.get("/sample", response_model=WorkflowDefinition)
  48. def get_sample_workflow() -> WorkflowDefinition:
  49. return WorkflowDefinition(
  50. code="sample_workflow",
  51. name="Sample Workflow",
  52. nodes=[
  53. NodeDefinition(id="start", type="llm"),
  54. NodeDefinition(id="end", type="answer"),
  55. ],
  56. edges=[EdgeDefinition(source="start", target="end")])
  57. @router.post("/sample", response_model=WorkflowDefinition)
  58. def get_sample_workflow_post() -> WorkflowDefinition:
  59. return get_sample_workflow()
  60. @router.post("/designer/validate", response_model=WorkflowDesignerValidateResponse)
  61. def validate_workflow_designer_dsl(
  62. payload: WorkflowDesignerValidateRequest,
  63. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDesignerValidateResponse:
  64. inspection = service.validate_designer_workflow(payload)
  65. return WorkflowDesignerValidateResponse.from_inspection(inspection)
  66. @router.post("/designer/debug", response_model=WorkflowDebuggerPlanResponse)
  67. def debug_workflow_designer_dsl(
  68. payload: WorkflowDebuggerPlanRequest,
  69. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDebuggerPlanResponse:
  70. plan = service.build_designer_debug_plan(payload)
  71. return WorkflowDebuggerPlanResponse.from_plan(plan)
  72. @router.post("/apps", response_model=AppResponse)
  73. def create_app(
  74. payload: AppCreateRequest,
  75. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> AppResponse:
  76. entity = service.create_app(payload)
  77. return AppResponse.from_entity(entity)
  78. @router.get("/apps", response_model=list[AppResponse])
  79. def list_apps(
  80. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[AppResponse]:
  81. return [AppResponse.from_entity(item) for item in service.list_apps()]
  82. @router.post("/apps/list", response_model=list[AppResponse])
  83. def list_apps_post(
  84. payload: AppListRequest,
  85. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[AppResponse]:
  86. return [AppResponse.from_entity(item) for item in service.list_apps()]
  87. @router.post("/apps/configs", response_model=AppConfigResponse)
  88. def create_app_config(
  89. payload: AppConfigCreateRequest,
  90. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> AppConfigResponse:
  91. entity = service.create_app_config(payload)
  92. return AppConfigResponse.from_entity(entity)
  93. @router.get("/apps/configs", response_model=list[AppConfigResponse])
  94. def list_app_configs(
  95. app_id: str = Query(...),
  96. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[AppConfigResponse]:
  97. return [AppConfigResponse.from_entity(item) for item in service.list_app_configs(app_id)]
  98. @router.post("/apps/configs/list", response_model=list[AppConfigResponse])
  99. def list_app_configs_post(
  100. payload: AppConfigListRequest,
  101. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[AppConfigResponse]:
  102. return [AppConfigResponse.from_entity(item) for item in service.list_app_configs(payload.app_id)]
  103. @router.post("", response_model=WorkflowDefinitionResponse)
  104. def create_workflow(
  105. payload: WorkflowCreateRequest,
  106. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDefinitionResponse:
  107. entity = service.create_workflow(payload)
  108. return WorkflowDefinitionResponse.from_entity(entity)
  109. @router.get("", response_model=list[WorkflowDefinitionResponse])
  110. def list_workflows(
  111. app_id: str | None = Query(default=None),
  112. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[WorkflowDefinitionResponse]:
  113. items = service.list_workflows(app_id=app_id)
  114. return [WorkflowDefinitionResponse.from_entity(item) for item in items]
  115. @router.post("/list", response_model=list[WorkflowDefinitionResponse])
  116. def list_workflows_post(
  117. payload: WorkflowListRequest,
  118. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[WorkflowDefinitionResponse]:
  119. items = service.list_workflows(app_id=payload.app_id)
  120. return [WorkflowDefinitionResponse.from_entity(item) for item in items]
  121. @router.post("/configs", response_model=WorkflowConfigResponse)
  122. def create_workflow_config(
  123. payload: WorkflowConfigCreateRequest,
  124. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowConfigResponse:
  125. try:
  126. entity = service.create_workflow_config(payload)
  127. except ValueError as exc:
  128. raise HTTPException(status_code=422, detail=str(exc)) from exc
  129. return WorkflowConfigResponse.from_entity(entity)
  130. @router.get("/configs", response_model=list[WorkflowConfigResponse])
  131. def list_workflow_configs(
  132. workflow_id: str = Query(...),
  133. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[WorkflowConfigResponse]:
  134. items = service.list_workflow_configs(workflow_id=workflow_id)
  135. return [WorkflowConfigResponse.from_entity(item) for item in items]
  136. @router.post("/configs/list", response_model=list[WorkflowConfigResponse])
  137. def list_workflow_configs_post(
  138. payload: WorkflowConfigListRequest,
  139. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> list[WorkflowConfigResponse]:
  140. items = service.list_workflow_configs(workflow_id=payload.workflow_id)
  141. return [WorkflowConfigResponse.from_entity(item) for item in items]
  142. @router.get("/configs/{workflow_config_id}", response_model=WorkflowConfigResponse)
  143. def get_workflow_config(
  144. workflow_config_id: str,
  145. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowConfigResponse:
  146. entity = service.get_workflow_config(workflow_config_id=workflow_config_id)
  147. if entity is None:
  148. raise HTTPException(status_code=404, detail=f"workflow_config not found: {workflow_config_id}")
  149. return WorkflowConfigResponse.from_entity(entity)
  150. @router.post("/configs/detail", response_model=WorkflowConfigResponse)
  151. def get_workflow_config_post(
  152. payload: WorkflowConfigDetailRequest,
  153. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowConfigResponse:
  154. entity = service.get_workflow_config(workflow_config_id=payload.workflow_config_id)
  155. if entity is None:
  156. raise HTTPException(
  157. status_code=404,
  158. detail=f"workflow_config not found: {payload.workflow_config_id}")
  159. return WorkflowConfigResponse.from_entity(entity)
  160. @router.get("/configs/{workflow_config_id}/debug", response_model=WorkflowDebuggerPlanResponse)
  161. def debug_workflow_config(
  162. workflow_config_id: str,
  163. max_preview_steps: int = Query(default=50, ge=1, le=500),
  164. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDebuggerPlanResponse:
  165. plan = service.build_config_debug_plan(
  166. workflow_config_id=workflow_config_id,
  167. max_preview_steps=max_preview_steps)
  168. if plan is None:
  169. raise HTTPException(status_code=404, detail=f"workflow_config not found: {workflow_config_id}")
  170. return WorkflowDebuggerPlanResponse.from_plan(plan)
  171. @router.post("/configs/debug", response_model=WorkflowDebuggerPlanResponse)
  172. def debug_workflow_config_post(
  173. payload: WorkflowConfigDebuggerPlanRequest,
  174. service: WorkflowApplicationService = Depends(get_workflow_application_service)) -> WorkflowDebuggerPlanResponse:
  175. plan = service.build_config_debug_plan(
  176. workflow_config_id=payload.workflow_config_id,
  177. max_preview_steps=payload.max_preview_steps)
  178. if plan is None:
  179. raise HTTPException(
  180. status_code=404,
  181. detail=f"workflow_config not found: {payload.workflow_config_id}")
  182. return WorkflowDebuggerPlanResponse.from_plan(plan)