ricecoder_execution/models.rs
1//! Data models for execution plans and results
2
3use serde::{Deserialize, Serialize};
4use std::time::Duration;
5use uuid::Uuid;
6
7/// Execution plan containing all steps to be executed
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ExecutionPlan {
10 /// Unique identifier for the plan
11 pub id: String,
12 /// Human-readable name for the plan
13 pub name: String,
14 /// Steps to execute in order
15 pub steps: Vec<ExecutionStep>,
16 /// Risk score for the plan
17 pub risk_score: RiskScore,
18 /// Estimated duration for execution
19 pub estimated_duration: Duration,
20 /// Estimated complexity level
21 pub estimated_complexity: ComplexityLevel,
22 /// Whether approval is required before execution
23 pub requires_approval: bool,
24 /// Whether the plan can be edited before execution
25 pub editable: bool,
26}
27
28/// A single step in an execution plan
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ExecutionStep {
31 /// Unique identifier for the step
32 pub id: String,
33 /// Human-readable description of the step
34 pub description: String,
35 /// The action to perform
36 pub action: StepAction,
37 /// Risk score for this specific step
38 pub risk_score: RiskScore,
39 /// IDs of steps that must complete before this one
40 pub dependencies: Vec<String>,
41 /// Optional rollback action to undo this step
42 pub rollback_action: Option<RollbackAction>,
43 /// Current status of the step
44 pub status: StepStatus,
45}
46
47/// Status of an execution step
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
49pub enum StepStatus {
50 /// Step is waiting to be executed
51 Pending,
52 /// Step is currently executing
53 Running,
54 /// Step completed successfully
55 Completed,
56 /// Step was skipped by user
57 Skipped,
58 /// Step failed during execution
59 Failed,
60 /// Step was rolled back after failure
61 RolledBack,
62}
63
64/// Action to perform in a step
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub enum StepAction {
67 /// Create a new file with content
68 CreateFile {
69 /// Path to the file (resolved via PathResolver)
70 path: String,
71 /// Content to write
72 content: String,
73 },
74 /// Modify an existing file
75 ModifyFile {
76 /// Path to the file (resolved via PathResolver)
77 path: String,
78 /// Diff to apply
79 diff: String,
80 },
81 /// Delete a file
82 DeleteFile {
83 /// Path to the file (resolved via PathResolver)
84 path: String,
85 },
86 /// Run a shell command
87 RunCommand {
88 /// Command to execute
89 command: String,
90 /// Command arguments
91 args: Vec<String>,
92 },
93 /// Run tests
94 RunTests {
95 /// Optional pattern to filter tests
96 pattern: Option<String>,
97 },
98}
99
100/// Risk score for a plan or step
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct RiskScore {
103 /// Risk level (Low, Medium, High, Critical)
104 pub level: RiskLevel,
105 /// Numeric score (0.0 to 1.0+)
106 pub score: f32,
107 /// Individual risk factors contributing to the score
108 pub factors: Vec<RiskFactor>,
109}
110
111/// Risk level classification
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
113pub enum RiskLevel {
114 /// Low risk - no approval required
115 Low,
116 /// Medium risk - approval may be required
117 Medium,
118 /// High risk - approval required
119 High,
120 /// Critical risk - approval required with detailed review
121 Critical,
122}
123
124/// Individual risk factor
125#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct RiskFactor {
127 /// Name of the risk factor
128 pub name: String,
129 /// Weight/contribution to overall score
130 pub weight: f32,
131 /// Description of the risk factor
132 pub description: String,
133}
134
135/// Complexity level of an execution plan
136#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
137pub enum ComplexityLevel {
138 /// Simple plan with few steps
139 #[default]
140 Simple,
141 /// Moderate complexity
142 Moderate,
143 /// Complex plan with many steps or dependencies
144 Complex,
145 /// Very complex plan
146 VeryComplex,
147}
148
149/// Result of executing a plan
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct ExecutionResult {
152 /// ID of the executed plan
153 pub plan_id: String,
154 /// Overall execution status
155 pub status: ExecutionStatus,
156 /// Results for each step
157 pub step_results: Vec<StepResult>,
158 /// Test results if tests were run
159 pub test_results: Option<TestResults>,
160 /// Total duration of execution
161 pub duration: Duration,
162 /// Whether rollback was performed
163 pub rollback_performed: bool,
164}
165
166/// Status of an execution
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
168pub enum ExecutionStatus {
169 /// Execution is pending
170 Pending,
171 /// Execution is in progress
172 Running,
173 /// Execution is waiting for approval
174 WaitingApproval,
175 /// Execution completed successfully
176 Completed,
177 /// Execution failed
178 Failed,
179 /// Execution was rolled back
180 RolledBack,
181 /// Execution is paused
182 Paused,
183}
184
185/// Result of executing a single step
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct StepResult {
188 /// ID of the step
189 pub step_id: String,
190 /// Whether the step succeeded
191 pub success: bool,
192 /// Error message if step failed
193 pub error: Option<String>,
194 /// Duration of step execution
195 pub duration: Duration,
196}
197
198/// Test results from running tests
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct TestResults {
201 /// Number of tests passed
202 pub passed: usize,
203 /// Number of tests failed
204 pub failed: usize,
205 /// Number of tests skipped
206 pub skipped: usize,
207 /// Details of test failures
208 pub failures: Vec<TestFailure>,
209 /// Test framework used
210 pub framework: TestFramework,
211}
212
213/// Details of a test failure
214#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct TestFailure {
216 /// Name of the test
217 pub name: String,
218 /// Failure message
219 pub message: String,
220 /// Optional location in code
221 pub location: Option<String>,
222}
223
224/// Test framework type
225#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
226pub enum TestFramework {
227 /// Rust (cargo test)
228 Rust,
229 /// TypeScript (npm test / yarn test)
230 TypeScript,
231 /// Python (pytest)
232 Python,
233 /// Other framework
234 Other,
235}
236
237/// Rollback action to undo a step
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct RollbackAction {
240 /// Type of rollback action
241 pub action_type: RollbackType,
242 /// Data for the rollback action
243 pub data: serde_json::Value,
244}
245
246/// Type of rollback action
247#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
248pub enum RollbackType {
249 /// Restore a file from backup
250 RestoreFile,
251 /// Delete a created file
252 DeleteFile,
253 /// Run a command to undo changes
254 RunCommand,
255}
256
257/// Execution mode
258#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
259pub enum ExecutionMode {
260 /// Execute all steps without user intervention
261 #[default]
262 Automatic,
263 /// Require approval for each step
264 StepByStep,
265 /// Preview changes without applying them
266 DryRun,
267}
268
269/// Execution state for pause/resume
270#[derive(Debug, Clone, Serialize, Deserialize)]
271pub struct ExecutionState {
272 /// ID of the execution
273 pub execution_id: String,
274 /// Current step index
275 pub current_step_index: usize,
276 /// Completed step results
277 pub completed_steps: Vec<StepResult>,
278 /// Execution mode
279 pub mode: ExecutionMode,
280 /// Timestamp when paused
281 pub paused_at: chrono::DateTime<chrono::Utc>,
282}
283
284impl ExecutionPlan {
285 /// Create a new execution plan
286 pub fn new(name: String, steps: Vec<ExecutionStep>) -> Self {
287 Self {
288 id: Uuid::new_v4().to_string(),
289 name,
290 steps,
291 risk_score: RiskScore {
292 level: RiskLevel::Low,
293 score: 0.0,
294 factors: Vec::new(),
295 },
296 estimated_duration: Duration::from_secs(0),
297 estimated_complexity: ComplexityLevel::Simple,
298 requires_approval: false,
299 editable: true,
300 }
301 }
302}
303
304impl ExecutionStep {
305 /// Create a new execution step
306 pub fn new(description: String, action: StepAction) -> Self {
307 Self {
308 id: Uuid::new_v4().to_string(),
309 description,
310 action,
311 risk_score: RiskScore {
312 level: RiskLevel::Low,
313 score: 0.0,
314 factors: Vec::new(),
315 },
316 dependencies: Vec::new(),
317 rollback_action: None,
318 status: StepStatus::Pending,
319 }
320 }
321}
322
323impl Default for RiskScore {
324 fn default() -> Self {
325 Self {
326 level: RiskLevel::Low,
327 score: 0.0,
328 factors: Vec::new(),
329 }
330 }
331}