Files
codex/codex-rs/analytics/src/turn_critical_path.rs
T
taohong-oai 33b16a9306 Report turn critical-path timing in analytics (#57209)
## What changed

Include critical-path capture status and duration totals in `codex_turn_event`, with categories for inference, auto review, user wait, tools, overhead, and unknown time. Count sampling and compaction as inference.

Distinguish `disabled`, `incomplete`, and `complete` capture. Emit null durations for disabled or incomplete capture so missing measurements are not reported as zero. Freeze the completion timestamp so repeated terminal notifications preserve the original measurement window.

## Testing

Add core and analytics tests for capture status, duration reporting, rounding, and repeated completion. Add app-server integration coverage for completed and interrupted turns with default, enabled, and disabled capture.

GitOrigin-RevId: c6c867120ee563ac48584c2f4b12df23acbabe06
2026-10-26 19:35:31 +00:00

60 lines
2.4 KiB
Rust

//! Turn critical-path facts and their nullable analytics fields.
//! Missing capture never becomes a zero-duration measurement.
use serde::Serialize;
/// Capture coverage for one finalized turn, independent of its completion status.
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)]
pub enum TurnCriticalPath {
#[default]
Disabled,
Incomplete,
Complete(TurnCriticalPathDurations),
}
/// Category totals over the server turn interval, truncated to milliseconds.
/// Sampling and compaction both contribute to inference. Independent truncation
/// can leave the category sum up to five milliseconds below duration_ms.
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct TurnCriticalPathDurations {
pub duration_ms: u64,
pub inference_ms: u64,
pub auto_review_ms: u64,
pub user_wait_ms: u64,
pub tools_ms: u64,
pub overhead_ms: u64,
pub unknown_ms: u64,
}
#[derive(Serialize)]
pub(crate) struct CriticalPathEventParams {
critical_path_status: &'static str,
critical_path_duration_ms: Option<u64>,
critical_path_inference_ms: Option<u64>,
critical_path_auto_review_ms: Option<u64>,
critical_path_user_wait_ms: Option<u64>,
critical_path_tools_ms: Option<u64>,
critical_path_overhead_ms: Option<u64>,
critical_path_unknown_ms: Option<u64>,
}
impl From<TurnCriticalPath> for CriticalPathEventParams {
fn from(path: TurnCriticalPath) -> Self {
let (status, durations) = match path {
TurnCriticalPath::Disabled => ("disabled", None),
TurnCriticalPath::Incomplete => ("incomplete", None),
TurnCriticalPath::Complete(durations) => ("complete", Some(durations)),
};
Self {
critical_path_status: status,
critical_path_duration_ms: durations.as_ref().map(|value| value.duration_ms),
critical_path_inference_ms: durations.as_ref().map(|value| value.inference_ms),
critical_path_auto_review_ms: durations.as_ref().map(|value| value.auto_review_ms),
critical_path_user_wait_ms: durations.as_ref().map(|value| value.user_wait_ms),
critical_path_tools_ms: durations.as_ref().map(|value| value.tools_ms),
critical_path_overhead_ms: durations.as_ref().map(|value| value.overhead_ms),
critical_path_unknown_ms: durations.as_ref().map(|value| value.unknown_ms),
}
}
}