agents board: a turns tab, and turn duration bounds past 10 s
The per-agent /stats page shows what the swarm agents board lacked about turns. The new tab reads the turn count and duration the harness already records: average duration, cache hit rate, tokens per turn, turns per hour by agent and by model, duration percentiles, and the wake source and result mixes. The duration histogram used the SDK default buckets, which stop at 10 s while a turn averages 24 s, so every p95 read a flat 10 s; it now has explicit bounds up to an hour.
This commit is contained in:
parent
666f8975a2
commit
aecde1dc75
1 changed files with 898 additions and 1 deletions
|
|
@ -43,6 +43,26 @@ use crate::turn_stats::TurnStatRow;
|
|||
/// two batch on the same rhythm.
|
||||
const EXPORT_INTERVAL: Duration = Duration::from_mins(1);
|
||||
|
||||
/// Bucket upper bounds of the turn-duration histogram, in milliseconds. The
|
||||
/// SDK's default bounds stop at 10 s, but a turn takes about 24 s on average,
|
||||
/// so with them every p95 read a flat 10 s. These run from half a second to an
|
||||
/// hour.
|
||||
const TURN_DURATION_BOUNDS_MS: [f64; 13] = [
|
||||
500.0,
|
||||
1_000.0,
|
||||
2_500.0,
|
||||
5_000.0,
|
||||
10_000.0,
|
||||
20_000.0,
|
||||
30_000.0,
|
||||
60_000.0,
|
||||
120_000.0,
|
||||
300_000.0,
|
||||
600_000.0,
|
||||
1_800_000.0,
|
||||
3_600_000.0,
|
||||
];
|
||||
|
||||
struct Instruments {
|
||||
/// Kept alive for the process lifetime — the `PeriodicReader` only
|
||||
/// exports while its provider lives.
|
||||
|
|
@ -198,6 +218,7 @@ fn build() -> Option<Instruments> {
|
|||
turn_duration_ms: meter
|
||||
.u64_histogram("hyperhive.agent.turn.duration")
|
||||
.with_unit("ms")
|
||||
.with_boundaries(TURN_DURATION_BOUNDS_MS.to_vec())
|
||||
.build(),
|
||||
turn_count: meter.u64_counter("hyperhive.agent.turn.count").build(),
|
||||
session_count: meter.u64_counter("hyperhive.agent.session.count").build(),
|
||||
|
|
@ -267,3 +288,20 @@ fn build_provider(interval: Duration) -> anyhow::Result<SdkMeterProvider> {
|
|||
pub fn enabled() -> bool {
|
||||
std::env::var("OTEL_EXPORTER_OTLP_ENDPOINT").is_ok_and(|s| !s.trim().is_empty())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::TURN_DURATION_BOUNDS_MS;
|
||||
|
||||
#[test]
|
||||
fn the_duration_bounds_ascend_and_reach_past_the_old_ten_second_ceiling() {
|
||||
// The SDK drops bounds that are not strictly ascending, which would
|
||||
// silently bring the default buckets (and the flat p95) back.
|
||||
assert!(TURN_DURATION_BOUNDS_MS.windows(2).all(|w| w[0] < w[1]));
|
||||
assert!(
|
||||
TURN_DURATION_BOUNDS_MS
|
||||
.last()
|
||||
.is_some_and(|&b| b > 10_000.0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue