Track code-mode cell lifecycle and result buffering time (#55653)

## What changed

- Add `CodeModeCellTiming` notifications for yielded executions, terminal waits, and unavailable cells, with thread, call, and cell identifiers.
- Measure how long completed results remain buffered before retrieval and carry `result_buffered_for` through the runtime, stdio protocol, and gRPC response metadata. Immediate delivery reports zero; waits without a completed result report no buffering measurement.
- Default missing buffering data to zero for compatibility with older hosts.

## Testing

Extend runtime tests to verify buffering duration with a paused clock and retrieval through termination. Add gRPC conversion tests for nanosecond precision, optional metadata, and the distinction between immediate delivery and no completed result.

GitOrigin-RevId: 60c0c5a3affa69ac3779bf1812fca50f5748af76
This commit is contained in:
Ruslan Nigmatullin
2026-10-20 18:53:06 +00:00
committed by copyberry
parent 801bd4d773
commit 87f3c3284e
38 changed files with 397 additions and 123 deletions
@@ -5,3 +5,7 @@ pub use code_mode_proto::codex::code_mode::v1::*;
tonic::include_proto!("codex.code_mode.v1");
pub const MAX_IDENTIFIER_BYTES: usize = 256;
/// Decimal nanoseconds a completed result was buffered before a wait or terminate retrieved it.
/// Zero means immediate delivery. Hosts omit this metadata if no completed result was retrieved.
pub const RESULT_BUFFERED_FOR_NS_METADATA: &str = "codex-code-mode-result-buffered-for-ns";
@@ -488,6 +488,7 @@ fn host_to_client_v1_variants_are_pinned() {
code_mode_host_duration_ns: 0,
cell_id: cell_id("missing-cell"),
content_items: Vec::new(),
result_buffered_for_ns: 0,
error_text: Some("cell not found".to_string()),
}),
},
@@ -499,6 +500,7 @@ fn host_to_client_v1_variants_are_pinned() {
"cell_id": "missing-cell",
"content_items": [],
"error_text": "cell not found",
"result_buffered_for_ns": 0,
"code_mode_host_duration_ns": 0,
},
},
@@ -335,6 +335,8 @@ pub enum WireRuntimeResponse {
cell_id: WireCellId,
content_items: Vec<WireContentItem>,
error_text: Option<String>,
#[serde(default)]
result_buffered_for_ns: u64,
code_mode_host_duration_ns: u64,
},
}
@@ -377,6 +379,7 @@ impl TryFrom<RuntimeResponse> for WireRuntimeResponse {
cell_id,
content_items,
error_text,
result_buffered_for,
code_mode_host_duration,
} => {
let code_mode_host_duration =
@@ -385,6 +388,8 @@ impl TryFrom<RuntimeResponse> for WireRuntimeResponse {
cell_id: cell_id.into(),
content_items: content_items.into_iter().map(Into::into).collect(),
error_text,
result_buffered_for_ns: u64::try_from(result_buffered_for.as_nanos())
.unwrap_or(u64::MAX),
code_mode_host_duration_ns: u64::try_from(code_mode_host_duration.as_nanos())
.unwrap_or(u64::MAX),
}
@@ -418,11 +423,13 @@ impl From<WireRuntimeResponse> for RuntimeResponse {
cell_id,
content_items,
error_text,
result_buffered_for_ns,
code_mode_host_duration_ns,
} => Self::Result {
cell_id: cell_id.into(),
content_items: content_items.into_iter().map(Into::into).collect(),
error_text,
result_buffered_for: Duration::from_nanos(result_buffered_for_ns),
code_mode_host_duration: Some(Duration::from_nanos(code_mode_host_duration_ns)),
},
}
@@ -43,6 +43,18 @@ pub enum WaitOutcome {
}
impl WaitOutcome {
/// How long a completed result waited for retrieval. Zero if it was delivered immediately,
/// or `None` if this wait did not retrieve a completed result.
pub fn result_buffered_for(&self) -> Option<Duration> {
match self {
Self::LiveCell(RuntimeResponse::Result {
result_buffered_for,
..
}) => Some(*result_buffered_for),
Self::LiveCell(_) | Self::MissingCell(_) => None,
}
}
/// Returns timing for this wait or termination request, when supplied by its host.
pub fn code_mode_host_duration(&self) -> Option<Duration> {
match self {
@@ -113,6 +125,9 @@ pub enum RuntimeResponse {
cell_id: CellId,
content_items: Vec<FunctionCallOutputContentItem>,
error_text: Option<String>,
/// Time between completion and retrieval when the result was buffered.
#[serde(default, skip_serializing_if = "Duration::is_zero")]
result_buffered_for: Duration,
#[serde(skip_serializing_if = "Option::is_none")]
code_mode_host_duration: Option<Duration>,
},
@@ -33,6 +33,7 @@ fn code_mode_host_duration_survives_runtime_and_stdio_serialization() {
RuntimeResponse::Result {
cell_id: CellId::new("completed-cell".to_string()),
content_items,
result_buffered_for: Duration::ZERO,
error_text: Some("execution failed".to_string()),
code_mode_host_duration: None,
},