1use tokio::sync::mpsc;
6
7#[derive(Debug, Clone)]
9pub enum TelemetryEvent {
10 EnergyUpdate {
12 node_id: String,
13 energy: f32,
14 components: EnergyComponents,
15 },
16 TaskStatusChange {
18 node_id: String,
19 status: TaskStatus,
20 goal: String,
21 },
22 TokensUsed { count: usize, total: usize },
24 Log(LogEntry),
26 SessionState(SessionState),
28}
29
30#[derive(Debug, Clone, Default)]
32pub struct EnergyComponents {
33 pub v_syn: f32,
35 pub v_str: f32,
37 pub v_log: f32,
39 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#[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#[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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137pub enum LogLevel {
138 Info,
139 Warning,
140 Error,
141 Success,
142}
143
144#[derive(Debug, Clone, Copy, PartialEq, Eq)]
146pub enum SessionState {
147 Planning,
148 Executing,
149 Paused,
150 Completed,
151 Failed,
152}
153
154pub type TelemetrySender = mpsc::UnboundedSender<TelemetryEvent>;
156
157pub type TelemetryReceiver = mpsc::UnboundedReceiver<TelemetryEvent>;
159
160pub fn create_telemetry_channel() -> (TelemetrySender, TelemetryReceiver) {
162 mpsc::unbounded_channel()
163}