code-mode: define transport-neutral runtime types (#29170)

## Summary

- introduce a private `session_runtime` boundary for cell creation
requests, observation modes, lifecycle events, output items, and tool
metadata
- update the cell actor and in-process service to use those
transport-neutral types
- keep cell ID allocation on the owning session side

## Motivation

Cell lifecycle vocabulary currently lives inside the cell actor
implementation. That makes the service adapter and future session
runtime depend on actor-specific types, increasing the size and
complexity of the runtime ownership change.

This is the first reviewable slice of the session-runtime stack. It
separates the transport-neutral data model without moving lifecycle
ownership or changing behavior.

Later slices will move session state behind this boundary, harden
terminal and shutdown behavior, and split cell creation from
observation.

## Behavior

There are no public API or user-visible behavior changes in this PR.

In particular:

- `CodeModeSession::execute` and `wait` are unchanged
- cell IDs remain allocated by the owning session
- cell admission, observation, termination, and shutdown behavior are
unchanged
This commit is contained in:
Channing Conger
2026-06-21 10:49:31 -07:00
committed by GitHub
Unverified
parent 6f5dd7b422
commit 6d993ca646
8 changed files with 114 additions and 91 deletions
@@ -5,10 +5,10 @@ use codex_code_mode_protocol::ImageDetail;
use codex_code_mode_protocol::ToolDefinition;
use codex_protocol::ToolName;
use super::CellImageDetail;
use super::CellOutputItem;
use super::CellRequest;
use super::CellToolKind;
use crate::session_runtime::CreateCellRequest as CellRequest;
use crate::session_runtime::ImageDetail as CellImageDetail;
use crate::session_runtime::OutputItem as CellOutputItem;
use crate::session_runtime::ToolKind as CellToolKind;
pub(super) fn runtime_request(request: CellRequest) -> ExecuteRequest {
ExecuteRequest {
+4 -8
View File
@@ -22,23 +22,19 @@ use self::conversions::output_item;
use self::conversions::runtime_request;
use self::types::CellCommand;
pub(crate) use self::types::CellError;
pub(crate) use self::types::CellEvent;
pub(crate) use self::types::CellEventFuture;
pub(crate) use self::types::CellHandle;
pub(crate) use self::types::CellHost;
pub(crate) use self::types::CellImageDetail;
pub(crate) use self::types::CellOutputItem;
pub(crate) use self::types::CellRequest;
pub(crate) use self::types::CellToolCall;
pub(crate) use self::types::CellToolDefinition;
pub(crate) use self::types::CellToolKind;
pub(crate) use self::types::CellToolName;
pub(crate) use self::types::ObserveMode;
use crate::runtime::PendingRuntimeMode;
use crate::runtime::RuntimeCommand;
use crate::runtime::RuntimeControlCommand;
use crate::runtime::RuntimeEvent;
use crate::runtime::spawn_runtime;
use crate::session_runtime::CellEvent;
use crate::session_runtime::CreateCellRequest as CellRequest;
use crate::session_runtime::ObserveMode;
use crate::session_runtime::ToolName as CellToolName;
pub(crate) struct CellActor;
@@ -11,6 +11,7 @@ use tokio::sync::oneshot;
use tokio_util::sync::CancellationToken;
use super::*;
use crate::session_runtime::OutputItem as CellOutputItem;
struct TestHost;
+7 -71
View File
@@ -4,40 +4,20 @@ use std::pin::Pin;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::time::Duration;
use serde_json::Value as JsonValue;
use tokio::sync::mpsc;
use tokio::sync::oneshot;
use tokio_util::sync::CancellationToken;
use crate::session_runtime::CellEvent;
use crate::session_runtime::ObserveMode;
use crate::session_runtime::ToolKind;
use crate::session_runtime::ToolName;
pub(crate) type CellEventFuture =
Pin<Box<dyn Future<Output = Result<CellEvent, CellError>> + Send + 'static>>;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum ObserveMode {
YieldAfter(Duration),
PendingFrontier,
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum CellEvent {
Yielded {
content_items: Vec<CellOutputItem>,
},
Pending {
content_items: Vec<CellOutputItem>,
pending_tool_call_ids: Vec<String>,
},
Completed {
content_items: Vec<CellOutputItem>,
error_text: Option<String>,
},
Terminated {
content_items: Vec<CellOutputItem>,
},
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum CellError {
Busy,
@@ -45,54 +25,10 @@ pub(crate) enum CellError {
Closed,
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum CellOutputItem {
Text {
text: String,
},
Image {
image_url: String,
detail: Option<CellImageDetail>,
},
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum CellImageDetail {
Auto,
Low,
High,
Original,
}
pub(crate) struct CellRequest {
pub(crate) tool_call_id: String,
pub(crate) enabled_tools: Vec<CellToolDefinition>,
pub(crate) source: String,
}
pub(crate) struct CellToolDefinition {
pub(crate) name: String,
pub(crate) tool_name: CellToolName,
pub(crate) description: String,
pub(crate) kind: CellToolKind,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct CellToolName {
pub(crate) name: String,
pub(crate) namespace: Option<String>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum CellToolKind {
Function,
Freeform,
}
pub(crate) struct CellToolCall {
pub(crate) id: String,
pub(crate) name: CellToolName,
pub(crate) kind: CellToolKind,
pub(crate) name: ToolName,
pub(crate) kind: ToolKind,
pub(crate) input: Option<JsonValue>,
}
+1
View File
@@ -1,6 +1,7 @@
mod cell_actor;
mod runtime;
mod service;
mod session_runtime;
pub use codex_code_mode_protocol::*;
pub use service::CodeModeService;
+8 -8
View File
@@ -33,18 +33,18 @@ use tokio_util::sync::CancellationToken;
use crate::cell_actor::CellActor;
use crate::cell_actor::CellError;
use crate::cell_actor::CellEvent;
use crate::cell_actor::CellEventFuture;
use crate::cell_actor::CellHandle;
use crate::cell_actor::CellHost;
use crate::cell_actor::CellImageDetail;
use crate::cell_actor::CellOutputItem;
use crate::cell_actor::CellRequest;
use crate::cell_actor::CellToolCall;
use crate::cell_actor::CellToolDefinition;
use crate::cell_actor::CellToolKind;
use crate::cell_actor::CellToolName;
use crate::cell_actor::ObserveMode;
use crate::session_runtime::CellEvent;
use crate::session_runtime::CreateCellRequest as CellRequest;
use crate::session_runtime::ImageDetail as CellImageDetail;
use crate::session_runtime::ObserveMode;
use crate::session_runtime::OutputItem as CellOutputItem;
use crate::session_runtime::ToolDefinition as CellToolDefinition;
use crate::session_runtime::ToolKind as CellToolKind;
use crate::session_runtime::ToolName as CellToolName;
pub struct NoopCodeModeSessionDelegate;
@@ -0,0 +1,10 @@
mod types;
pub(crate) use self::types::CellEvent;
pub(crate) use self::types::CreateCellRequest;
pub(crate) use self::types::ImageDetail;
pub(crate) use self::types::ObserveMode;
pub(crate) use self::types::OutputItem;
pub(crate) use self::types::ToolDefinition;
pub(crate) use self::types::ToolKind;
pub(crate) use self::types::ToolName;
@@ -0,0 +1,79 @@
use std::time::Duration;
/// Selects the next observable frontier for a running cell.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum ObserveMode {
YieldAfter(Duration),
PendingFrontier,
}
/// An observable cell lifecycle event.
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum CellEvent {
Yielded {
content_items: Vec<OutputItem>,
},
Pending {
content_items: Vec<OutputItem>,
pending_tool_call_ids: Vec<String>,
},
Completed {
content_items: Vec<OutputItem>,
error_text: Option<String>,
},
Terminated {
content_items: Vec<OutputItem>,
},
}
/// Output emitted by a cell since its preceding observation.
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum OutputItem {
Text {
text: String,
},
Image {
image_url: String,
detail: Option<ImageDetail>,
},
}
/// Requested image fidelity for an output image.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum ImageDetail {
Auto,
Low,
High,
Original,
}
/// Transport-neutral input for creating a cell.
///
/// The owning session assigns the cell ID when it admits the request.
pub(crate) struct CreateCellRequest {
pub(crate) tool_call_id: String,
pub(crate) enabled_tools: Vec<ToolDefinition>,
pub(crate) source: String,
}
/// Tool metadata exposed to code running inside a cell.
pub(crate) struct ToolDefinition {
pub(crate) name: String,
pub(crate) tool_name: ToolName,
pub(crate) description: String,
pub(crate) kind: ToolKind,
}
/// A tool name with an optional namespace.
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct ToolName {
pub(crate) name: String,
pub(crate) namespace: Option<String>,
}
/// The JavaScript calling convention for a tool.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum ToolKind {
Function,
Freeform,
}