agent stats: track tool calls by type with EWMA, add Stats pane

- RunStats now includes tool_calls_by_type HashMap
- AutoAgent tracks runs, last_stats, and EWMA for tool calls/failures
- Removed duplicate stats fields from individual agent structs
- Fixed provenance to use bare agent name (no "agent:" prefix)
- Subconscious screen now displays both agent types consistently
- Added Stats pane showing tool call breakdown sorted by count

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-11 22:12:46 -04:00
parent e9e7458013
commit 314ae9c4cb
4 changed files with 169 additions and 55 deletions

View file

@ -294,6 +294,7 @@ pub struct SubconsciousSnapshot {
pub enabled: bool,
pub current_phase: String,
pub turn: usize,
pub runs: usize,
pub last_run_secs_ago: Option<f64>,
/// Shared handle to the forked agent — UI locks to read entries.
pub forked_agent: Option<Arc<crate::agent::Agent>>,
@ -303,6 +304,9 @@ pub struct SubconsciousSnapshot {
pub state: std::collections::BTreeMap<String, String>,
/// Recent store activity for this agent: (key, timestamp), newest first.
pub history: Vec<(String, i64)>,
pub last_stats: Option<crate::agent::oneshot::RunStats>,
pub tool_calls_ewma: f64,
pub tool_failures_ewma: f64,
}
struct SubconsciousAgent {
@ -367,11 +371,15 @@ impl SubconsciousAgent {
enabled: self.auto.enabled,
current_phase: self.auto.current_phase.clone(),
turn: self.auto.turn,
runs: self.auto.runs,
last_run_secs_ago: self.last_run.map(|t| t.elapsed().as_secs_f64()),
forked_agent: self.forked_agent.clone(),
fork_point: self.fork_point,
state: state.clone(),
history,
last_stats: self.auto.last_stats.clone(),
tool_calls_ewma: self.auto.tool_calls_ewma,
tool_failures_ewma: self.auto.tool_failures_ewma,
}
}
}
@ -614,7 +622,8 @@ impl Subconscious {
self.agents[idx].handle = Some(tokio::spawn(async move {
let result = auto.run_forked_shared(&forked, &keys, &st, &recent).await;
crate::agent::oneshot::save_agent_log(&auto.name, &forked).await;
let stats = crate::agent::oneshot::save_agent_log(&auto.name, &forked).await;
auto.update_stats(stats);
(auto, result)
}));
}