feat(stats): cache hit-rate, tokens/turn, and result trend over time
First slice of #1424 (per-agent /stats enrichments): - Backend: add per-bucket result_counts to the stats Snapshot (mirrors model_counts), so result outcomes can be charted over time, not just as a window total. - Frontend: two new summary chips — cache hit-rate % (cached input vs all input-side tokens) and avg tokens/turn — both derived from the existing per-bucket token sums. Plus a stacked result-trend chart so error / rate-limit / compaction spikes are visible across the window. Hive-wide aggregate, cost estimate, and container resource load land in follow-up PRs.
This commit is contained in:
parent
86f0de751f
commit
ded7474b2b
3 changed files with 63 additions and 0 deletions
|
|
@ -129,6 +129,10 @@ pub struct Bucket {
|
|||
/// affects token cost, so this lets the operator line model usage
|
||||
/// up against the cost series over time.
|
||||
pub model_counts: HashMap<String, u64>,
|
||||
/// Turn count per `result_kind` in this bucket. Lets the stats
|
||||
/// page chart error / rate-limit / compaction outcomes *over time*
|
||||
/// (the window-total lives in `Snapshot::result_mix`).
|
||||
pub result_counts: HashMap<String, u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
|
@ -243,6 +247,7 @@ fn snapshot(path: &Path, window: Window) -> Result<Snapshot> {
|
|||
acc.ctx_sum = acc.ctx_sum.saturating_add(r.last_input_tokens);
|
||||
acc.ctx_max = acc.ctx_max.max(r.last_input_tokens);
|
||||
*acc.model_counts.entry(r.model.clone()).or_insert(0) += 1;
|
||||
*acc.result_counts.entry(r.result_kind.clone()).or_insert(0) += 1;
|
||||
|
||||
all_durations.push(r.duration_ms.max(0));
|
||||
*wake_totals.entry(r.wake_from).or_insert(0) += 1;
|
||||
|
|
@ -304,6 +309,7 @@ struct BucketAcc {
|
|||
ctx_sum: u64,
|
||||
ctx_max: u64,
|
||||
model_counts: HashMap<String, u64>,
|
||||
result_counts: HashMap<String, u64>,
|
||||
}
|
||||
|
||||
fn fill_buckets(
|
||||
|
|
@ -352,6 +358,7 @@ fn fill_buckets(
|
|||
avg_ctx_tokens: avg_ctx,
|
||||
max_ctx_tokens: acc.ctx_max,
|
||||
model_counts: acc.model_counts.clone(),
|
||||
result_counts: acc.result_counts.clone(),
|
||||
}
|
||||
} else {
|
||||
Bucket {
|
||||
|
|
@ -367,6 +374,7 @@ fn fill_buckets(
|
|||
avg_ctx_tokens: 0.0,
|
||||
max_ctx_tokens: 0,
|
||||
model_counts: HashMap::new(),
|
||||
result_counts: HashMap::new(),
|
||||
}
|
||||
};
|
||||
out.push(bucket);
|
||||
|
|
|
|||
Loading…
Reference in a new issue