Scope code mode cell IDs to the host process

This commit is contained in:
Channing Conger
2026-06-10 17:22:19 -07:00
parent 72d48f9df9
commit 945eb18f37
3 changed files with 51 additions and 7 deletions

View File

@@ -49,6 +49,7 @@ async fn run() -> Result<(), String> {
sessions: Mutex::new(HashMap::new()),
next_session_id: AtomicU64::new(1),
peer,
host_id: std::process::id().to_string(),
});
let writer = tokio::spawn(async move {
@@ -110,8 +111,12 @@ impl HostState {
});
self.sessions.lock().await.insert(
session_id,
Arc::new(CodeModeService::with_delegate(delegate)),
Arc::new(CodeModeService::with_delegate_and_cell_id_prefix(
delegate,
self.host_id.clone(),
)),
);
host_id: String,
self.respond(request_id, Ok(HostResponse::SessionCreated { session_id }))
.await;
}

View File

@@ -25,6 +25,7 @@ async fn serves_code_mode_sessions_over_stdio() {
.kill_on_drop(true)
.spawn()
.expect("spawn codex-code-mode-host");
let host_id = child.id().expect("host process id");
let mut stdin = child.stdin.take().expect("host stdin");
let mut stdout = child.stdout.take().expect("host stdout");
@@ -70,6 +71,7 @@ async fn serves_code_mode_sessions_over_stdio() {
}) => cell_id,
message => panic!("unexpected execute response: {message:?}"),
};
assert_eq!(cell_id.as_str(), format!("{host_id}_1"));
let response = match read_frame(&mut stdout)
.await
.expect("initial response frame")

View File

@@ -93,6 +93,7 @@ struct Inner {
cells: Mutex<HashMap<CellId, CellHandle>>,
delegate: Arc<dyn CodeModeSessionDelegate>,
shutting_down: AtomicBool,
cell_id_prefix: Option<String>,
next_cell_id: AtomicU64,
}
@@ -106,24 +107,38 @@ impl CodeModeService {
}
pub fn with_delegate(delegate: Arc<dyn CodeModeSessionDelegate>) -> Self {
Self::with_inner(delegate, None)
}
pub fn with_delegate_and_cell_id_prefix(
delegate: Arc<dyn CodeModeSessionDelegate>,
cell_id_prefix: String,
) -> Self {
Self::with_inner(delegate, Some(cell_id_prefix))
}
fn with_inner(
delegate: Arc<dyn CodeModeSessionDelegate>,
cell_id_prefix: Option<String>,
) -> Self {
Self {
inner: Arc::new(Inner {
stored_values: Mutex::new(HashMap::new()),
cells: Mutex::new(HashMap::new()),
delegate,
shutting_down: AtomicBool::new(false),
cell_id_prefix,
next_cell_id: AtomicU64::new(1),
}),
}
}
fn allocate_cell_id(&self) -> CellId {
CellId::new(
self.inner
.next_cell_id
.fetch_add(1, Ordering::Relaxed)
.to_string(),
)
let cell_id = self.inner.next_cell_id.fetch_add(1, Ordering::Relaxed);
CellId::new(match &self.inner.cell_id_prefix {
Some(prefix) => format!("{prefix}_{cell_id}"),
None => cell_id.to_string(),
})
}
pub async fn execute(&self, request: ExecuteRequest) -> Result<StartedCell, String> {
@@ -823,6 +838,7 @@ mod tests {
})
}
cell_id_prefix: None,
#[tokio::test]
async fn synchronous_exit_returns_successfully() {
let service = CodeModeService::new();
@@ -853,6 +869,27 @@ mod tests {
async fn stored_values_are_shared_between_cells_but_not_sessions() {
let first_session = CodeModeService::new();
let second_session = CodeModeService::new();
#[tokio::test]
async fn cell_ids_include_the_configured_host_prefix() {
let service = CodeModeService::with_delegate_and_cell_id_prefix(
Arc::new(NoopCodeModeSessionDelegate),
"host7".to_string(),
);
let response = execute(&service, execute_request("text('done');")).await;
assert_eq!(
response,
RuntimeResponse::Result {
cell_id: cell_id("host7_1"),
content_items: vec![FunctionCallOutputContentItem::InputText {
text: "done".to_string(),
}],
error_text: None,
}
);
}
let write_response = execute(
&first_session,