use std::sync::Arc;
use tracing::{debug, info, warn};
use crate::activity::monitor::{ActivityMonitor, LlmClassifier};
use crate::session_manager::{ManagedSessionState, SessionManager};
use super::config::SupervisorConfig;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct TickReport {
pub observed: usize,
pub resumed: Vec<String>,
pub resume_failures: usize,
pub classified: usize,
}
pub async fn run_tick<C: LlmClassifier>(
mgr: &Arc<SessionManager>,
cfg: &SupervisorConfig,
monitor: Option<&ActivityMonitor<C>>,
) -> TickReport {
let records = mgr.list().await;
let mut report = TickReport {
observed: records.len(),
..Default::default()
};
for record in records {
match record.state {
ManagedSessionState::Stopped if cfg.auto_resume => match mgr.resume(&record.id).await {
Ok(_) => {
info!(
id = %record.id,
name = %record.tmux_name,
"supervisor: auto-resumed stopped session"
);
report.resumed.push(record.id.to_string());
}
Err(e) => {
warn!(
id = %record.id,
name = %record.tmux_name,
"supervisor: auto-resume failed: {e}"
);
report.resume_failures += 1;
}
},
ManagedSessionState::Active if cfg.classify_idle => {
if let Some(monitor) = monitor
&& classify_active(mgr, monitor, &record.id, &record.tmux_name).await
{
report.classified += 1;
}
}
_ => {}
}
}
debug!(
observed = report.observed,
resumed = report.resumed.len(),
resume_failures = report.resume_failures,
classified = report.classified,
"supervisor: sweep complete"
);
report
}
async fn classify_active<C: LlmClassifier>(
mgr: &Arc<SessionManager>,
monitor: &ActivityMonitor<C>,
id: &crate::session_manager::ManagedSessionId,
tmux_name: &str,
) -> bool {
let pane = match mgr.capture_pane(id, 60).await {
Ok(text) => text,
Err(e) => {
warn!(id = %id, name = %tmux_name, "supervisor: pane capture failed: {e}");
return false;
}
};
match monitor.check(&id.to_string(), &pane).await {
Ok(result) => {
debug!(
id = %id,
name = %tmux_name,
state = ?result.verdict.state,
cache_hit = result.cache_hit,
"supervisor: classified idle session"
);
true
}
Err(e) => {
warn!(id = %id, name = %tmux_name, "supervisor: classification failed: {e}");
false
}
}
}