feat(dashboard): ST4TS tab — hive-wide stats view
Builds the dashboard UI on the /api/stats-hive endpoint: a new ST4TS tab showing swarm totals (active agents, turns, tokens, labelled est cost), a busiest-first per-agent table, and a model-mix bar list. Plain tables/CSS bars — no chart lib in the dashboard bundle; per-agent trend charts stay on each agent's own /stats page. Fetched on tab activation + window change (pull-only, no SSE). Also adds conn.busy_timeout(500ms) in hive_stats read_agent per review: turn_stats is rollback-journal, so a read landing mid-INSERT would hit SQLITE_BUSY and silently drop that active agent — wait the write out.
This commit is contained in:
parent
447a84e8a6
commit
8e74dda4c5
4 changed files with 263 additions and 2 deletions
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use rusqlite::{Connection, OpenFlags};
|
||||
use serde::Serialize;
|
||||
|
|
@ -177,6 +177,10 @@ fn u64_from_i64(v: i64) -> u64 {
|
|||
/// the whole endpoint.
|
||||
fn read_agent(path: &Path, from: i64) -> rusqlite::Result<AgentAgg> {
|
||||
let conn = Connection::open_with_flags(path, OpenFlags::SQLITE_OPEN_READ_ONLY)?;
|
||||
// turn_stats is rollback-journal (not WAL): a read landing while the
|
||||
// harness is mid-INSERT would get SQLITE_BUSY and drop that active
|
||||
// agent from the rollup. Wait out the brief write instead.
|
||||
conn.busy_timeout(Duration::from_millis(500))?;
|
||||
let mut stmt = conn.prepare(
|
||||
"SELECT model, input_tokens, output_tokens,
|
||||
cache_read_input_tokens, cache_creation_input_tokens
|
||||
|
|
|
|||
Loading…
Reference in a new issue