use std::sync::Arc; use codex_code_mode_protocol::CellId; use codex_code_mode_protocol::CodeModeNestedToolCall; use codex_code_mode_protocol::CodeModeSessionDelegate; use codex_code_mode_protocol::NotificationFuture; use codex_code_mode_protocol::RuntimeResponse; use codex_code_mode_protocol::StartedCell; use codex_code_mode_protocol::ToolInvocationFuture; use codex_code_mode_protocol::WaitOutcome; use tokio_util::sync::CancellationToken; pub(super) struct GenerationDelegate { pub(super) delegate: Arc, pub(super) generation: u64, } impl CodeModeSessionDelegate for GenerationDelegate { fn invoke_tool<'a>( &'a self, mut invocation: CodeModeNestedToolCall, cancellation_token: CancellationToken, ) -> ToolInvocationFuture<'a> { invocation.cell_id = public_cell_id(self.generation, &invocation.cell_id); self.delegate.invoke_tool(invocation, cancellation_token) } fn notify<'a>( &'a self, call_id: String, cell_id: CellId, text: String, cancellation_token: CancellationToken, ) -> NotificationFuture<'a> { self.delegate.notify( call_id, public_cell_id(self.generation, &cell_id), text, cancellation_token, ) } fn cell_closed(&self, cell_id: &CellId) { self.delegate .cell_closed(&public_cell_id(self.generation, cell_id)); } } fn public_cell_id(generation: u64, cell_id: &CellId) -> CellId { if generation == 1 { cell_id.clone() } else { CellId::new(format!("g{generation}:{cell_id}")) } } pub(super) fn remote_cell_id(generation: u64, cell_id: &CellId) -> Result { if generation == 1 { return Ok(cell_id.clone()); } let prefix = format!("g{generation}:"); cell_id .as_str() .strip_prefix(&prefix) .map(|cell_id| CellId::new(cell_id.to_string())) .ok_or_else(|| "cell belongs to a stale code-mode host generation".to_string()) } pub(super) fn public_started_cell(generation: u64, started: StartedCell) -> StartedCell { if generation == 1 { return started; } let cell_id = public_cell_id(generation, &started.cell_id); StartedCell::from_future(cell_id, async move { started .initial_response() .await .map(|response| public_runtime_response(generation, response)) }) } fn public_runtime_response(generation: u64, response: RuntimeResponse) -> RuntimeResponse { match response { RuntimeResponse::Yielded { cell_id, content_items, code_mode_host_duration, } => RuntimeResponse::Yielded { cell_id: public_cell_id(generation, &cell_id), content_items, code_mode_host_duration, }, RuntimeResponse::Terminated { cell_id, content_items, code_mode_host_duration, } => RuntimeResponse::Terminated { cell_id: public_cell_id(generation, &cell_id), content_items, code_mode_host_duration, }, RuntimeResponse::Result { cell_id, content_items, error_text, code_mode_host_duration, } => RuntimeResponse::Result { cell_id: public_cell_id(generation, &cell_id), content_items, error_text, code_mode_host_duration, }, } } pub(super) fn public_wait_outcome(generation: u64, outcome: WaitOutcome) -> WaitOutcome { match outcome { WaitOutcome::LiveCell(response) => { WaitOutcome::LiveCell(public_runtime_response(generation, response)) } WaitOutcome::MissingCell(response) => { WaitOutcome::MissingCell(public_runtime_response(generation, response)) } } } #[cfg(test)] #[path = "generation_tests.rs"] mod tests;