Skip to main content

brainwires_agents/task_manager/
time_tracking.rs

1//! Time Tracking
2//!
3//! Types and functions for task time tracking and statistics.
4
5use brainwires_core::TaskStatus;
6
7/// Statistics about tasks
8#[derive(Debug, Clone, Default)]
9pub struct TaskStats {
10    /// Total number of tasks.
11    pub total: usize,
12    /// Number of pending tasks.
13    pub pending: usize,
14    /// Number of in-progress tasks.
15    pub in_progress: usize,
16    /// Number of completed tasks.
17    pub completed: usize,
18    /// Number of failed tasks.
19    pub failed: usize,
20    /// Number of blocked tasks.
21    pub blocked: usize,
22    /// Number of skipped tasks.
23    pub skipped: usize,
24}
25
26/// Time tracking information for a single task
27#[derive(Debug, Clone)]
28pub struct TaskTimeInfo {
29    /// Task identifier.
30    pub task_id: String,
31    /// Human-readable task description.
32    pub description: String,
33    /// Current task status.
34    pub status: TaskStatus,
35    /// Unix timestamp when the task started.
36    pub started_at: Option<i64>,
37    /// Unix timestamp when the task completed.
38    pub completed_at: Option<i64>,
39    /// Total duration in seconds (for completed tasks).
40    pub duration_secs: Option<i64>,
41    /// Elapsed seconds since start (for in-progress tasks).
42    pub elapsed_secs: Option<i64>,
43}
44
45impl TaskTimeInfo {
46    /// Format duration as human-readable string
47    pub fn format_duration(&self) -> String {
48        if let Some(duration) = self.duration_secs {
49            format_duration_secs(duration)
50        } else if let Some(elapsed) = self.elapsed_secs {
51            format!("{}...", format_duration_secs(elapsed))
52        } else {
53            "-".to_string()
54        }
55    }
56}
57
58/// Time statistics for all tasks
59#[derive(Debug, Clone, Default)]
60pub struct TimeStats {
61    /// Sum of all completed task durations in seconds.
62    pub total_duration_secs: i64,
63    /// Number of completed tasks.
64    pub completed_tasks: usize,
65    /// Average task duration in seconds.
66    pub average_duration_secs: Option<i64>,
67    /// Total elapsed time for in-progress tasks in seconds.
68    pub current_elapsed_secs: i64,
69    /// Number of currently in-progress tasks.
70    pub in_progress_tasks: usize,
71}
72
73impl TimeStats {
74    /// Format total duration as human-readable string
75    pub fn format_total(&self) -> String {
76        format_duration_secs(self.total_duration_secs)
77    }
78
79    /// Format average duration as human-readable string
80    pub fn format_average(&self) -> String {
81        if let Some(avg) = self.average_duration_secs {
82            format_duration_secs(avg)
83        } else {
84            "-".to_string()
85        }
86    }
87
88    /// Format current elapsed time (in-progress tasks)
89    pub fn format_elapsed(&self) -> String {
90        format_duration_secs(self.current_elapsed_secs)
91    }
92}
93
94/// Format duration in seconds as human-readable string (e.g., "2m 34s", "1h 5m")
95pub fn format_duration_secs(secs: i64) -> String {
96    if secs < 0 {
97        return "-".to_string();
98    }
99
100    let hours = secs / 3600;
101    let minutes = (secs % 3600) / 60;
102    let seconds = secs % 60;
103
104    if hours > 0 {
105        format!("{}h {}m", hours, minutes)
106    } else if minutes > 0 {
107        format!("{}m {}s", minutes, seconds)
108    } else {
109        format!("{}s", seconds)
110    }
111}