Add gRPC-backed code-mode sessions (#38041)

## What changed

- Add `GrpcCodeModeSessionProvider` for opening code-mode sessions over HTTP/2 or an existing `tonic` channel.
- Support execution, waiting, termination, per-session limits, cell-closure callbacks, and graceful shutdown over the gRPC protocol.
- Bound transport waits and error messages, validate host identifiers and responses, and clean up abandoned executions and observers.

## Testing

- Add end-to-end TCP tests covering session persistence, cancellation, concurrent waits, shutdown, cell cleanup, and independent yield limits.
- Add unit coverage for protocol conversion, deadlines, and session lifecycle state.

GitOrigin-RevId: d4729ce608ad4b42a99744b07e1f230e46cb24ec
This commit is contained in:
Channing Conger
2026-08-11 17:17:58 +00:00
committed by copyberry
parent b2543af02b
commit 1e557a554e
20 changed files with 2275 additions and 17 deletions

View File

@@ -134,7 +134,8 @@ message CellClosed {
string execution_id = 1;
string cell_id = 2;
// All lower sequences must be observed before the client retires the cell.
// Last tool-call sequence issued before closure. Clients may retire the cell
// immediately and reject tool calls delivered after its closure.
uint64 final_tool_call_sequence = 3;
}

View File

@@ -3,3 +3,5 @@ pub use code_mode_proto::codex::code_mode::v1::*;
#[cfg(not(codex_bazel))]
tonic::include_proto!("codex.code_mode.v1");
pub const MAX_IDENTIFIER_BYTES: usize = 256;

View File

@@ -62,27 +62,31 @@ pub struct StartedCell {
impl StartedCell {
pub fn new(cell_id: CellId, initial_response_rx: oneshot::Receiver<RuntimeResponse>) -> Self {
Self {
cell_id,
initial_response: Box::pin(async move {
initial_response_rx
.await
.map_err(|_| "exec runtime ended unexpectedly".to_string())
}),
}
Self::from_future(cell_id, async move {
initial_response_rx
.await
.map_err(|_| "exec runtime ended unexpectedly".to_string())
})
}
pub fn from_result_receiver(
cell_id: CellId,
initial_response_rx: oneshot::Receiver<Result<RuntimeResponse, String>>,
) -> Self {
Self::from_future(cell_id, async move {
initial_response_rx
.await
.map_err(|_| "exec runtime ended unexpectedly".to_string())?
})
}
pub fn from_future(
cell_id: CellId,
initial_response: impl Future<Output = Result<RuntimeResponse, String>> + Send + 'static,
) -> Self {
Self {
cell_id,
initial_response: Box::pin(async move {
initial_response_rx
.await
.map_err(|_| "exec runtime ended unexpectedly".to_string())?
}),
initial_response: Box::pin(initial_response),
}
}