Skip to main content

ralph_workflow/reducer/
event.rs

1//! Pipeline event types for reducer architecture.
2//!
3//! Defines all possible events that can occur during pipeline execution.
4//! Each event represents a state transition that the reducer handles.
5
6use crate::agents::AgentRole;
7use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9
10/// Pipeline phases for checkpoint tracking.
11///
12/// These phases represent the major stages of the Ralph pipeline.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14pub enum PipelinePhase {
15    Planning,
16    Development,
17    Review,
18    CommitMessage,
19    FinalValidation,
20    /// Finalizing phase for cleanup operations before completion.
21    ///
22    /// This phase handles:
23    /// - Restoring PROMPT.md write permissions
24    /// - Any other cleanup that must go through the effect system
25    Finalizing,
26    Complete,
27    Interrupted,
28}
29
30impl std::fmt::Display for PipelinePhase {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        match self {
33            Self::Planning => write!(f, "Planning"),
34            Self::Development => write!(f, "Development"),
35            Self::Review => write!(f, "Review"),
36            Self::CommitMessage => write!(f, "Commit Message"),
37            Self::FinalValidation => write!(f, "Final Validation"),
38            Self::Finalizing => write!(f, "Finalizing"),
39            Self::Complete => write!(f, "Complete"),
40            Self::Interrupted => write!(f, "Interrupted"),
41        }
42    }
43}
44
45/// Pipeline events representing all state transitions.
46///
47/// Each event captures an observable transition in pipeline execution.
48/// The reducer handles these events to compute new state.
49#[derive(Clone, Serialize, Deserialize, Debug)]
50pub enum PipelineEvent {
51    PipelineStarted,
52    PipelineResumed {
53        from_checkpoint: bool,
54    },
55    PipelineCompleted,
56    PipelineAborted {
57        reason: String,
58    },
59
60    PlanningPhaseStarted,
61    PlanningPhaseCompleted,
62
63    DevelopmentPhaseStarted,
64    DevelopmentIterationStarted {
65        iteration: u32,
66    },
67    PlanGenerationStarted {
68        iteration: u32,
69    },
70    PlanGenerationCompleted {
71        iteration: u32,
72        valid: bool,
73    },
74    DevelopmentIterationCompleted {
75        iteration: u32,
76        output_valid: bool,
77    },
78    ContextCleaned,
79    DevelopmentPhaseCompleted,
80
81    ReviewPhaseStarted,
82    ReviewPassStarted {
83        pass: u32,
84    },
85    ReviewCompleted {
86        pass: u32,
87        issues_found: bool,
88    },
89    FixAttemptStarted {
90        pass: u32,
91    },
92    FixAttemptCompleted {
93        pass: u32,
94        changes_made: bool,
95    },
96    ReviewPhaseCompleted {
97        early_exit: bool,
98    },
99
100    AgentInvocationStarted {
101        role: AgentRole,
102        agent: String,
103        model: Option<String>,
104    },
105    AgentInvocationSucceeded {
106        role: AgentRole,
107        agent: String,
108    },
109    AgentInvocationFailed {
110        role: AgentRole,
111        agent: String,
112        exit_code: i32,
113        error_kind: AgentErrorKind,
114        retriable: bool,
115    },
116    AgentFallbackTriggered {
117        role: AgentRole,
118        from_agent: String,
119        to_agent: String,
120    },
121    AgentModelFallbackTriggered {
122        role: AgentRole,
123        agent: String,
124        from_model: String,
125        to_model: String,
126    },
127    AgentRetryCycleStarted {
128        role: AgentRole,
129        cycle: u32,
130    },
131    AgentChainExhausted {
132        role: AgentRole,
133    },
134    AgentChainInitialized {
135        role: AgentRole,
136        agents: Vec<String>,
137    },
138
139    RebaseStarted {
140        phase: RebasePhase,
141        target_branch: String,
142    },
143    RebaseConflictDetected {
144        files: Vec<PathBuf>,
145    },
146    RebaseConflictResolved {
147        files: Vec<PathBuf>,
148    },
149    RebaseSucceeded {
150        phase: RebasePhase,
151        new_head: String,
152    },
153    RebaseFailed {
154        phase: RebasePhase,
155        reason: String,
156    },
157    RebaseAborted {
158        phase: RebasePhase,
159        restored_to: String,
160    },
161    RebaseSkipped {
162        phase: RebasePhase,
163        reason: String,
164    },
165
166    CommitGenerationStarted,
167    CommitMessageGenerated {
168        message: String,
169        attempt: u32,
170    },
171    CommitMessageValidationFailed {
172        reason: String,
173        attempt: u32,
174    },
175    CommitCreated {
176        hash: String,
177        message: String,
178    },
179    CommitGenerationFailed {
180        reason: String,
181    },
182    CommitSkipped {
183        reason: String,
184    },
185
186    CheckpointSaved {
187        trigger: CheckpointTrigger,
188    },
189
190    /// Finalization phase started.
191    FinalizingStarted,
192
193    /// PROMPT.md write permissions have been restored.
194    ///
195    /// This event is emitted after the RestorePromptPermissions effect
196    /// successfully restores write permissions on PROMPT.md.
197    PromptPermissionsRestored,
198}
199
200/// Rebase phase (initial or post-review).
201#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
202pub enum RebasePhase {
203    Initial,
204    PostReview,
205}
206
207/// Error kind for agent failures.
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
209pub enum AgentErrorKind {
210    Network,
211    Authentication,
212    RateLimit,
213    Timeout,
214    InternalError,
215    ModelUnavailable,
216    ParsingError,
217    FileSystem,
218}
219
220/// Conflict resolution strategy.
221#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
222pub enum ConflictStrategy {
223    Abort,
224    Continue,
225    Skip,
226}
227
228/// Checkpoint save trigger.
229#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
230pub enum CheckpointTrigger {
231    PhaseTransition,
232    IterationComplete,
233    BeforeRebase,
234    Interrupt,
235}
236
237#[cfg(test)]
238mod tests {
239    use super::*;
240
241    #[test]
242    fn test_pipeline_phase_display() {
243        assert_eq!(format!("{}", PipelinePhase::Planning), "Planning");
244        assert_eq!(format!("{}", PipelinePhase::Development), "Development");
245        assert_eq!(format!("{}", PipelinePhase::Review), "Review");
246        assert_eq!(
247            format!("{}", PipelinePhase::CommitMessage),
248            "Commit Message"
249        );
250        assert_eq!(
251            format!("{}", PipelinePhase::FinalValidation),
252            "Final Validation"
253        );
254        assert_eq!(format!("{}", PipelinePhase::Finalizing), "Finalizing");
255        assert_eq!(format!("{}", PipelinePhase::Complete), "Complete");
256        assert_eq!(format!("{}", PipelinePhase::Interrupted), "Interrupted");
257    }
258}