Skip to main content

ironflow_api/entities/
step.rs

1//! Step-related DTOs.
2
3use chrono::{DateTime, Utc};
4use ironflow_store::models::{Step, StepKind, StepStatus};
5use rust_decimal::Decimal;
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use uuid::Uuid;
9
10/// Step response DTO — public API representation of a step.
11///
12/// # Examples
13///
14/// ```
15/// use ironflow_store::models::Step;
16/// use ironflow_api::entities::StepResponse;
17/// ```
18#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
19#[derive(Debug, Serialize, Deserialize)]
20pub struct StepResponse {
21    /// Unique step identifier.
22    pub id: Uuid,
23    /// Parent run ID.
24    pub run_id: Uuid,
25    /// Step name.
26    pub name: String,
27    /// Step operation type.
28    #[cfg_attr(feature = "openapi", schema(value_type = String))]
29    pub kind: StepKind,
30    /// Execution order (0-based).
31    pub position: u32,
32    /// Current status.
33    pub status: StepStatus,
34    /// Input configuration.
35    #[cfg_attr(feature = "openapi", schema(value_type = Option<std::collections::HashMap<String, serde_json::Value>>))]
36    pub input: Option<Value>,
37    /// Step output.
38    #[cfg_attr(feature = "openapi", schema(value_type = Option<std::collections::HashMap<String, serde_json::Value>>))]
39    pub output: Option<Value>,
40    /// Optional error message.
41    pub error: Option<String>,
42    /// Execution duration in milliseconds.
43    pub duration_ms: u64,
44    /// Cost in USD.
45    #[cfg_attr(feature = "openapi", schema(value_type = f64))]
46    pub cost_usd: Decimal,
47    /// Input token count (agent steps).
48    pub input_tokens: Option<u64>,
49    /// Output token count (agent steps).
50    pub output_tokens: Option<u64>,
51    /// When created.
52    pub created_at: DateTime<Utc>,
53    /// When updated.
54    pub updated_at: DateTime<Utc>,
55    /// When execution started.
56    pub started_at: Option<DateTime<Utc>>,
57    /// When execution completed.
58    pub completed_at: Option<DateTime<Utc>>,
59    /// IDs of steps this step depends on (direct dependencies).
60    pub dependencies: Vec<Uuid>,
61    /// Verbose conversation trace for agent steps (thinking blocks, tool
62    /// calls, tool results, per-turn usage). `None` when verbose mode was
63    /// off or the step is not an agent step.
64    #[cfg_attr(feature = "openapi", schema(value_type = Option<serde_json::Value>))]
65    pub debug_messages: Option<Value>,
66}
67
68impl StepResponse {
69    /// Build a response from a step entity with pre-resolved dependencies.
70    pub fn with_dependencies(step: Step, dependencies: Vec<Uuid>) -> Self {
71        StepResponse {
72            id: step.id,
73            run_id: step.run_id,
74            name: step.name,
75            kind: step.kind,
76            position: step.position,
77            status: step.status.state,
78            input: step.input,
79            output: step.output,
80            error: step.error,
81            duration_ms: step.duration_ms,
82            cost_usd: step.cost_usd,
83            input_tokens: step.input_tokens,
84            output_tokens: step.output_tokens,
85            created_at: step.created_at,
86            updated_at: step.updated_at,
87            started_at: step.started_at,
88            completed_at: step.completed_at,
89            dependencies,
90            debug_messages: step.debug_messages,
91        }
92    }
93}
94
95impl From<Step> for StepResponse {
96    fn from(step: Step) -> Self {
97        Self::with_dependencies(step, Vec::new())
98    }
99}