ares/api/handlers/
workflows.rs1use crate::{
6 auth::middleware::AuthUser,
7 types::{AgentContext, Result, WorkflowRequest},
8 workflows::{WorkflowEngine, WorkflowOutput},
9 AppState,
10};
11use axum::{
12 extract::{Path, State},
13 Json,
14};
15use uuid::Uuid;
16
17#[utoipa::path(
22 post,
23 path = "/api/workflows/{workflow_name}",
24 request_body = WorkflowRequest,
25 responses(
26 (status = 200, description = "Workflow executed successfully", body = WorkflowOutput),
27 (status = 400, description = "Invalid input"),
28 (status = 401, description = "Unauthorized"),
29 (status = 404, description = "Workflow not found")
30 ),
31 params(
32 ("workflow_name" = String, Path, description = "Name of the workflow to execute")
33 ),
34 tag = "workflows",
35 security(("bearer" = []))
36)]
37pub async fn execute_workflow(
38 State(state): State<AppState>,
39 AuthUser(claims): AuthUser,
40 Path(workflow_name): Path<String>,
41 Json(payload): Json<WorkflowRequest>,
42) -> Result<Json<WorkflowOutput>> {
43 let workflow_engine = WorkflowEngine::new(state.clone());
45
46 if !workflow_engine.has_workflow(&workflow_name) {
48 return Err(crate::types::AppError::NotFound(format!(
49 "Workflow '{}' not found",
50 workflow_name
51 )));
52 }
53
54 let context = AgentContext {
56 user_id: claims.sub.clone(),
57 session_id: Uuid::new_v4().to_string(),
58 conversation_history: vec![],
59 user_memory: None,
60 };
61
62 let output = workflow_engine
64 .execute_workflow(&workflow_name, &payload.query, &context)
65 .await?;
66
67 Ok(Json(output))
68}
69
70#[utoipa::path(
74 get,
75 path = "/api/workflows",
76 responses(
77 (status = 200, description = "List of available workflows"),
78 (status = 401, description = "Unauthorized")
79 ),
80 tag = "workflows",
81 security(("bearer" = []))
82)]
83pub async fn list_workflows(
84 State(state): State<AppState>,
85 AuthUser(_claims): AuthUser,
86) -> Result<Json<Vec<WorkflowInfo>>> {
87 let config = state.config_manager.config();
88
89 let workflows: Vec<WorkflowInfo> = config
90 .workflows
91 .iter()
92 .map(|(name, wf)| WorkflowInfo {
93 name: name.clone(),
94 entry_agent: wf.entry_agent.clone(),
95 fallback_agent: wf.fallback_agent.clone(),
96 max_depth: wf.max_depth,
97 max_iterations: wf.max_iterations,
98 parallel_subagents: wf.parallel_subagents,
99 })
100 .collect();
101
102 Ok(Json(workflows))
103}
104
105#[derive(Debug, serde::Serialize, utoipa::ToSchema)]
107pub struct WorkflowInfo {
108 pub name: String,
110 pub entry_agent: String,
112 pub fallback_agent: Option<String>,
114 pub max_depth: u8,
116 pub max_iterations: u8,
118 pub parallel_subagents: bool,
120}