mirror of
https://github.com/openai/codex.git
synced 2026-09-04 15:08:45 +00:00
## Summary - add the `code_mode_host` feature flag and select `ProcessOwnedCodeModeSessionProvider` in `CodeModeService` when enabled - initialize code-mode sessions lazily so a missing host reports a tool error without failing thread startup - resolve `codex-code-mode-host` beside the running Codex binary by default while preserving `CODEX_CODE_MODE_HOST_PATH` as an override - add unit and end-to-end coverage for host resolution and graceful missing-host behavior ## Why This wires the process-owned session client from #30112 into the core service behind an opt-in rollout gate. Packaged Codex installations can place the helper in the same `bin` directory as the main executable without relying on `PATH`, while development and custom installations can continue to override the helper path. ## Stack - Depends on #30112 - Base branch: `cconger/process-owned-session-runtime-4-client` ## Validation Build `codex` and `codex-code-mode-host` `CODEX_CODE_MODE_HOST_PATH="$PWD/target/debug/codex-code-mode-host" ./target/debug/codex --enable code_mode_host`
104 lines
2.7 KiB
Rust
104 lines
2.7 KiB
Rust
use std::io;
|
|
use std::path::PathBuf;
|
|
use std::sync::Arc;
|
|
|
|
use codex_code_mode_protocol::CodeModeSessionProvider;
|
|
|
|
use super::ProcessOwnedCodeModeSession;
|
|
use super::ProcessOwnedCodeModeSessionProvider;
|
|
use super::resolve_host_program;
|
|
use crate::NoopCodeModeSessionDelegate;
|
|
|
|
#[test]
|
|
fn provider_reuses_its_live_process_host() {
|
|
let provider = ProcessOwnedCodeModeSessionProvider::default();
|
|
|
|
let first = provider.process_host();
|
|
let second = provider.process_host();
|
|
|
|
assert!(Arc::ptr_eq(&first, &second));
|
|
}
|
|
|
|
#[test]
|
|
fn host_program_override_takes_precedence() {
|
|
assert_eq!(
|
|
resolve_host_program(
|
|
Some("custom-code-mode-host".into()),
|
|
Ok(PathBuf::from("/opt/codex/bin/codex")),
|
|
),
|
|
PathBuf::from("custom-code-mode-host")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn host_program_is_next_to_the_main_executable_even_when_missing() {
|
|
let executable_name = if cfg!(windows) {
|
|
"codex-code-mode-host.exe"
|
|
} else {
|
|
"codex-code-mode-host"
|
|
};
|
|
|
|
assert_eq!(
|
|
resolve_host_program(
|
|
/*override_path*/ None,
|
|
Ok(PathBuf::from("/opt/codex/bin/codex")),
|
|
),
|
|
PathBuf::from("/opt/codex/bin").join(executable_name)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn host_program_falls_back_to_its_name_when_main_executable_is_unknown() {
|
|
let executable_name = if cfg!(windows) {
|
|
"codex-code-mode-host.exe"
|
|
} else {
|
|
"codex-code-mode-host"
|
|
};
|
|
|
|
assert_eq!(
|
|
resolve_host_program(
|
|
/*override_path*/ None,
|
|
Err(io::Error::new(
|
|
io::ErrorKind::NotFound,
|
|
"missing executable"
|
|
)),
|
|
),
|
|
PathBuf::from(executable_name)
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn provider_reports_host_spawn_failure() {
|
|
let provider = ProcessOwnedCodeModeSessionProvider::with_host_program(
|
|
"codex-code-mode-host-does-not-exist".into(),
|
|
);
|
|
|
|
let error = provider
|
|
.create_session(Arc::new(NoopCodeModeSessionDelegate))
|
|
.await
|
|
.err()
|
|
.expect("session creation should fail");
|
|
|
|
assert!(error.contains("failed to spawn code-mode host"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn shutdown_before_open_does_not_spawn_the_host() {
|
|
let session = ProcessOwnedCodeModeSession::new();
|
|
|
|
session.shutdown().await.expect("shutdown session");
|
|
let error = session
|
|
.execute(codex_code_mode_protocol::ExecuteRequest {
|
|
tool_call_id: "call-1".to_string(),
|
|
enabled_tools: Vec::new(),
|
|
source: "text('unreachable')".to_string(),
|
|
yield_time_ms: None,
|
|
max_output_tokens: None,
|
|
})
|
|
.await
|
|
.err()
|
|
.expect("shutdown session should reject execution");
|
|
|
|
assert_eq!(error, "code mode session is shutting down");
|
|
}
|