perspt_tui/
telemetry.rs

1//! Telemetry module for real-time orchestrator updates
2//!
3//! Provides event types and channels for dashboard communication.
4
5use tokio::sync::mpsc;
6
7/// Telemetry event types from the orchestrator
8#[derive(Debug, Clone)]
9pub enum TelemetryEvent {
10    /// Lyapunov Energy update for a node
11    EnergyUpdate {
12        node_id: String,
13        energy: f32,
14        components: EnergyComponents,
15    },
16    /// Task status change
17    TaskStatusChange {
18        node_id: String,
19        status: TaskStatus,
20        goal: String,
21    },
22    /// Token usage update
23    TokensUsed { count: usize, total: usize },
24    /// Log message for activity feed
25    Log(LogEntry),
26    /// Session state change
27    SessionState(SessionState),
28}
29
30/// Energy components for detailed display
31#[derive(Debug, Clone, Default)]
32pub struct EnergyComponents {
33    /// Syntactic energy (LSP diagnostics)
34    pub v_syn: f32,
35    /// Structural energy (contract violations)
36    pub v_str: f32,
37    /// Logic energy (test failures)
38    pub v_log: f32,
39    /// Total composite energy
40    pub total: f32,
41}
42
43impl EnergyComponents {
44    pub fn new(v_syn: f32, v_str: f32, v_log: f32, alpha: f32, beta: f32, gamma: f32) -> Self {
45        Self {
46            v_syn,
47            v_str,
48            v_log,
49            total: alpha * v_syn + beta * v_str + gamma * v_log,
50        }
51    }
52
53    pub fn is_stable(&self, epsilon: f32) -> bool {
54        self.total < epsilon
55    }
56}
57
58/// Task status enum
59#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum TaskStatus {
61    Pending,
62    Running,
63    Verifying,
64    Completed,
65    Failed,
66    Escalated,
67}
68
69impl TaskStatus {
70    pub fn icon(&self) -> &'static str {
71        match self {
72            TaskStatus::Pending => "○",
73            TaskStatus::Running => "◐",
74            TaskStatus::Verifying => "◑",
75            TaskStatus::Completed => "●",
76            TaskStatus::Failed => "✗",
77            TaskStatus::Escalated => "⚠",
78        }
79    }
80
81    pub fn as_str(&self) -> &'static str {
82        match self {
83            TaskStatus::Pending => "pending",
84            TaskStatus::Running => "running",
85            TaskStatus::Verifying => "verifying",
86            TaskStatus::Completed => "completed",
87            TaskStatus::Failed => "failed",
88            TaskStatus::Escalated => "escalated",
89        }
90    }
91}
92
93/// Log entry for activity feed
94#[derive(Debug, Clone)]
95pub struct LogEntry {
96    pub level: LogLevel,
97    pub message: String,
98    pub timestamp: std::time::Instant,
99}
100
101impl LogEntry {
102    pub fn info(message: impl Into<String>) -> Self {
103        Self {
104            level: LogLevel::Info,
105            message: message.into(),
106            timestamp: std::time::Instant::now(),
107        }
108    }
109
110    pub fn warning(message: impl Into<String>) -> Self {
111        Self {
112            level: LogLevel::Warning,
113            message: message.into(),
114            timestamp: std::time::Instant::now(),
115        }
116    }
117
118    pub fn error(message: impl Into<String>) -> Self {
119        Self {
120            level: LogLevel::Error,
121            message: message.into(),
122            timestamp: std::time::Instant::now(),
123        }
124    }
125
126    pub fn success(message: impl Into<String>) -> Self {
127        Self {
128            level: LogLevel::Success,
129            message: message.into(),
130            timestamp: std::time::Instant::now(),
131        }
132    }
133}
134
135/// Log level
136#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137pub enum LogLevel {
138    Info,
139    Warning,
140    Error,
141    Success,
142}
143
144/// Session state
145#[derive(Debug, Clone, Copy, PartialEq, Eq)]
146pub enum SessionState {
147    Planning,
148    Executing,
149    Paused,
150    Completed,
151    Failed,
152}
153
154/// Type alias for telemetry sender
155pub type TelemetrySender = mpsc::UnboundedSender<TelemetryEvent>;
156
157/// Type alias for telemetry receiver
158pub type TelemetryReceiver = mpsc::UnboundedReceiver<TelemetryEvent>;
159
160/// Create a new telemetry channel
161pub fn create_telemetry_channel() -> (TelemetrySender, TelemetryReceiver) {
162    mpsc::unbounded_channel()
163}