Persist agent stats across restarts, add per-tool metrics grid
Stats now survive daemon restarts via ~/.consciousness/agent-stats.json, loaded into a global Mutex<HashMap> on first access. Each tool type tracks last count, EWMA (alpha=0.3), and total calls. UI shows a grid view: tool | last | avg | total, sorted by total desc. Failures row appears at bottom if any occurred. Also fixes temperature/priority not being applied to spawned agents. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
314ae9c4cb
commit
f408bb5d86
4 changed files with 148 additions and 56 deletions
|
|
@ -124,8 +124,8 @@ impl ScreenView for SubconsciousScreen {
|
|||
.map(|s| s.state.values().map(|v| v.lines().count() + 1).sum::<usize>())
|
||||
.unwrap_or(0);
|
||||
let output_height = (output_lines as u16 + 2).min(left.height / 5).max(3);
|
||||
let stats_lines = self.selected_stats(app)
|
||||
.map(|s| s.tool_calls_by_type.len())
|
||||
let stats_lines = self.selected_persisted_stats(app)
|
||||
.map(|s| s.by_tool.len())
|
||||
.unwrap_or(0);
|
||||
let stats_height = (stats_lines as u16 + 2).min(left.height / 5).max(3);
|
||||
let [list_area, output_area, stats_area, history_area] = Layout::vertical([
|
||||
|
|
@ -191,17 +191,10 @@ impl SubconsciousScreen {
|
|||
.unwrap_or(&[])
|
||||
}
|
||||
|
||||
/// Get last run stats for the selected agent.
|
||||
fn selected_stats<'a>(&self, app: &'a App) -> Option<&'a crate::agent::oneshot::RunStats> {
|
||||
let idx = self.selected();
|
||||
let sub_count = app.agent_state.len();
|
||||
if idx < sub_count {
|
||||
return app.agent_state.get(idx)
|
||||
.and_then(|s| s.last_stats.as_ref());
|
||||
}
|
||||
idx.checked_sub(sub_count + 1)
|
||||
.and_then(|i| app.unconscious_state.get(i))
|
||||
.and_then(|s| s.last_stats.as_ref())
|
||||
/// Get persisted stats for the selected agent.
|
||||
fn selected_persisted_stats(&self, app: &App) -> Option<crate::agent::oneshot::PersistedStats> {
|
||||
let name = self.selected_agent_name(app)?;
|
||||
Some(crate::agent::oneshot::get_stats(&name))
|
||||
}
|
||||
|
||||
fn output_sections(&self, app: &App) -> Vec<SectionView> {
|
||||
|
|
@ -355,21 +348,46 @@ impl SubconsciousScreen {
|
|||
|
||||
fn draw_stats(&mut self, frame: &mut Frame, area: Rect, app: &App) {
|
||||
let dim = Style::default().fg(Color::DarkGray);
|
||||
let header_style = Style::default().fg(Color::DarkGray);
|
||||
let name_style = Style::default().fg(Color::Cyan);
|
||||
let count_style = Style::default().fg(Color::Yellow);
|
||||
let num_style = Style::default().fg(Color::Yellow);
|
||||
|
||||
let mut lines: Vec<Line> = Vec::new();
|
||||
|
||||
if let Some(stats) = self.selected_stats(app) {
|
||||
// Sort by count descending
|
||||
let mut tools: Vec<_> = stats.tool_calls_by_type.iter().collect();
|
||||
tools.sort_by(|a, b| b.1.cmp(a.1));
|
||||
|
||||
for (name, count) in tools {
|
||||
if let Some(stats) = self.selected_persisted_stats(app) {
|
||||
if !stats.by_tool.is_empty() {
|
||||
// Header
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(format!(" {:>3} ", count), count_style),
|
||||
Span::styled(name.as_str(), name_style),
|
||||
Span::styled(" tool ", header_style),
|
||||
Span::styled("last ", header_style),
|
||||
Span::styled(" avg ", header_style),
|
||||
Span::styled("total", header_style),
|
||||
]));
|
||||
|
||||
// Sort by total descending
|
||||
let mut tools: Vec<_> = stats.by_tool.iter().collect();
|
||||
tools.sort_by(|a, b| b.1.total.cmp(&a.1.total));
|
||||
|
||||
for (name, tool_stats) in tools {
|
||||
let short_name = name.strip_prefix("memory_").unwrap_or(name);
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(format!(" {:<20} ", short_name), name_style),
|
||||
Span::styled(format!("{:>4} ", tool_stats.last), num_style),
|
||||
Span::styled(format!("{:>4.1} ", tool_stats.ewma), dim),
|
||||
Span::styled(format!("{:>5}", tool_stats.total), num_style),
|
||||
]));
|
||||
}
|
||||
|
||||
// Failures row if any
|
||||
if stats.failures.total > 0 {
|
||||
lines.push(Line::raw(""));
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(" failures ", Style::default().fg(Color::Red)),
|
||||
Span::styled(format!("{:>4} ", stats.failures.last), num_style),
|
||||
Span::styled(format!("{:>4.1} ", stats.failures.ewma), dim),
|
||||
Span::styled(format!("{:>5}", stats.failures.total), num_style),
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue