From 6d993ca6464570993e9312096d77b964e64bfab5 Mon Sep 17 00:00:00 2001 From: Channing Conger Date: Sun, 21 Jun 2026 10:49:31 -0700 Subject: [PATCH] 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 --- .../code-mode/src/cell_actor/conversions.rs | 8 +- codex-rs/code-mode/src/cell_actor/mod.rs | 12 +-- codex-rs/code-mode/src/cell_actor/tests.rs | 1 + codex-rs/code-mode/src/cell_actor/types.rs | 78 ++---------------- codex-rs/code-mode/src/lib.rs | 1 + codex-rs/code-mode/src/service.rs | 16 ++-- codex-rs/code-mode/src/session_runtime/mod.rs | 10 +++ .../code-mode/src/session_runtime/types.rs | 79 +++++++++++++++++++ 8 files changed, 114 insertions(+), 91 deletions(-) create mode 100644 codex-rs/code-mode/src/session_runtime/mod.rs create mode 100644 codex-rs/code-mode/src/session_runtime/types.rs diff --git a/codex-rs/code-mode/src/cell_actor/conversions.rs b/codex-rs/code-mode/src/cell_actor/conversions.rs index ebc12d29f..7fb2a25c6 100644 --- a/codex-rs/code-mode/src/cell_actor/conversions.rs +++ b/codex-rs/code-mode/src/cell_actor/conversions.rs @@ -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 { diff --git a/codex-rs/code-mode/src/cell_actor/mod.rs b/codex-rs/code-mode/src/cell_actor/mod.rs index d42ce48a2..6e0ffb9e0 100644 --- a/codex-rs/code-mode/src/cell_actor/mod.rs +++ b/codex-rs/code-mode/src/cell_actor/mod.rs @@ -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; diff --git a/codex-rs/code-mode/src/cell_actor/tests.rs b/codex-rs/code-mode/src/cell_actor/tests.rs index 218f1fcde..d7b72a103 100644 --- a/codex-rs/code-mode/src/cell_actor/tests.rs +++ b/codex-rs/code-mode/src/cell_actor/tests.rs @@ -11,6 +11,7 @@ use tokio::sync::oneshot; use tokio_util::sync::CancellationToken; use super::*; +use crate::session_runtime::OutputItem as CellOutputItem; struct TestHost; diff --git a/codex-rs/code-mode/src/cell_actor/types.rs b/codex-rs/code-mode/src/cell_actor/types.rs index aef0b5211..d82f898e7 100644 --- a/codex-rs/code-mode/src/cell_actor/types.rs +++ b/codex-rs/code-mode/src/cell_actor/types.rs @@ -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> + 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, - }, - Pending { - content_items: Vec, - pending_tool_call_ids: Vec, - }, - Completed { - content_items: Vec, - error_text: Option, - }, - Terminated { - content_items: Vec, - }, -} - #[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, - }, -} - -#[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, - 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, -} - -#[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, } diff --git a/codex-rs/code-mode/src/lib.rs b/codex-rs/code-mode/src/lib.rs index 76f8aa9b9..cbe8bfe6d 100644 --- a/codex-rs/code-mode/src/lib.rs +++ b/codex-rs/code-mode/src/lib.rs @@ -1,6 +1,7 @@ mod cell_actor; mod runtime; mod service; +mod session_runtime; pub use codex_code_mode_protocol::*; pub use service::CodeModeService; diff --git a/codex-rs/code-mode/src/service.rs b/codex-rs/code-mode/src/service.rs index 4c8fa517a..bf32156a0 100644 --- a/codex-rs/code-mode/src/service.rs +++ b/codex-rs/code-mode/src/service.rs @@ -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; diff --git a/codex-rs/code-mode/src/session_runtime/mod.rs b/codex-rs/code-mode/src/session_runtime/mod.rs new file mode 100644 index 000000000..bb09e0e43 --- /dev/null +++ b/codex-rs/code-mode/src/session_runtime/mod.rs @@ -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; diff --git a/codex-rs/code-mode/src/session_runtime/types.rs b/codex-rs/code-mode/src/session_runtime/types.rs new file mode 100644 index 000000000..f3719c96c --- /dev/null +++ b/codex-rs/code-mode/src/session_runtime/types.rs @@ -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, + }, + Pending { + content_items: Vec, + pending_tool_call_ids: Vec, + }, + Completed { + content_items: Vec, + error_text: Option, + }, + Terminated { + content_items: Vec, + }, +} + +/// 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, + }, +} + +/// 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, + 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, +} + +/// The JavaScript calling convention for a tool. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub(crate) enum ToolKind { + Function, + Freeform, +}