forked from kent/consciousness
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
|
|
@ -365,21 +365,23 @@ impl SubconsciousAgent {
|
|||
}
|
||||
|
||||
fn snapshot(&self, state: &std::collections::BTreeMap<String, String>, history: Vec<(String, i64)>) -> SubconsciousSnapshot {
|
||||
let stats = crate::agent::oneshot::get_stats(&self.name);
|
||||
let tool_calls_ewma: f64 = stats.by_tool.values().map(|t| t.ewma).sum();
|
||||
SubconsciousSnapshot {
|
||||
name: self.name.clone(),
|
||||
running: self.is_running(),
|
||||
enabled: self.auto.enabled,
|
||||
current_phase: self.auto.current_phase.clone(),
|
||||
turn: self.auto.turn,
|
||||
runs: self.auto.runs,
|
||||
runs: stats.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,
|
||||
last_stats: stats.last_stats.clone(),
|
||||
tool_calls_ewma,
|
||||
tool_failures_ewma: stats.failures.ewma,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -485,7 +487,7 @@ impl Subconscious {
|
|||
any_finished = true;
|
||||
|
||||
let (auto_back, result) = handle.await.unwrap_or_else(
|
||||
|e| (AutoAgent::new(String::new(), vec![], vec![], 0.0, 0),
|
||||
|e| (AutoAgent::new(String::new(), vec![], vec![], 0.6, 0),
|
||||
Err(format!("task panicked: {}", e))));
|
||||
self.agents[i].auto = auto_back;
|
||||
|
||||
|
|
@ -584,7 +586,7 @@ impl Subconscious {
|
|||
self.agents[i].last_trigger_bytes = conversation_bytes;
|
||||
|
||||
let auto = std::mem::replace(&mut self.agents[i].auto,
|
||||
AutoAgent::new(String::new(), vec![], vec![], 0.0, 0));
|
||||
AutoAgent::new(String::new(), vec![], vec![], 0.6, 0));
|
||||
to_run.push((i, auto));
|
||||
}
|
||||
|
||||
|
|
@ -604,9 +606,10 @@ impl Subconscious {
|
|||
{
|
||||
let mut st = forked.state.lock().await;
|
||||
st.provenance = auto.name.clone();
|
||||
st.temperature = auto.temperature;
|
||||
// Surface agent gets near-interactive priority;
|
||||
// other subconscious agents get lower priority.
|
||||
st.priority = Some(if auto.name == "surface" { 1 } else { 2 });
|
||||
st.priority = Some(if auto.name == "surface" { 1 } else { auto.priority });
|
||||
}
|
||||
let fork_point = forked.context.lock().await.conversation().len();
|
||||
|
||||
|
|
|
|||
|
|
@ -142,17 +142,19 @@ impl Unconscious {
|
|||
self.agents.iter().map(|a| {
|
||||
let history = store.map(|st| st.recent_by_provenance(&a.name, 30))
|
||||
.unwrap_or_default();
|
||||
let stats = crate::agent::oneshot::get_stats(&a.name);
|
||||
let tool_calls_ewma: f64 = stats.by_tool.values().map(|t| t.ewma).sum();
|
||||
UnconsciousSnapshot {
|
||||
name: a.name.clone(),
|
||||
running: a.is_running(),
|
||||
enabled: a.enabled,
|
||||
runs: a.auto.runs,
|
||||
runs: stats.runs,
|
||||
last_run_secs_ago: a.last_run.map(|t| t.elapsed().as_secs_f64()),
|
||||
agent: a.agent.clone(),
|
||||
last_stats: a.auto.last_stats.clone(),
|
||||
last_stats: stats.last_stats.clone(),
|
||||
history,
|
||||
tool_calls_ewma: a.auto.tool_calls_ewma,
|
||||
tool_failures_ewma: a.auto.tool_failures_ewma,
|
||||
tool_calls_ewma,
|
||||
tool_failures_ewma: stats.failures.ewma,
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
|
@ -186,7 +188,7 @@ impl Unconscious {
|
|||
agent.auto = auto_back;
|
||||
match result {
|
||||
Ok(_) => dbglog!("[unconscious] {} completed (run {})",
|
||||
agent.name, agent.auto.runs),
|
||||
agent.name, crate::agent::oneshot::get_stats(&agent.name).runs),
|
||||
Err(e) => dbglog!("[unconscious] {} failed: {}", agent.name, e),
|
||||
}
|
||||
}
|
||||
|
|
@ -242,7 +244,7 @@ impl Unconscious {
|
|||
|
||||
// Swap auto out, replace steps with resolved prompts
|
||||
let mut auto = std::mem::replace(&mut self.agents[idx].auto,
|
||||
AutoAgent::new(String::new(), vec![], vec![], 0.0, 0));
|
||||
AutoAgent::new(String::new(), vec![], vec![], 0.6, 0));
|
||||
let orig_steps = std::mem::replace(&mut auto.steps,
|
||||
batch.steps.iter().map(|s| AutoStep {
|
||||
prompt: s.prompt.clone(),
|
||||
|
|
@ -291,7 +293,8 @@ impl Unconscious {
|
|||
{
|
||||
let mut st = agent.state.lock().await;
|
||||
st.provenance = auto.name.clone();
|
||||
st.priority = Some(10);
|
||||
st.priority = Some(auto.priority);
|
||||
st.temperature = auto.temperature;
|
||||
}
|
||||
|
||||
self.agents[idx].agent = Some(agent.clone());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue