From cfa91028df1e0317d6ca247f9fca6a1cff9a4649 Mon Sep 17 00:00:00 2001 From: Rounak Jain Date: Fri, 19 Jun 2026 03:04:45 +0000 Subject: [PATCH] Respect the image generation feature gate for the standalone tool --- codex-rs/core/src/tools/spec_plan.rs | 2 +- codex-rs/core/tests/suite/responses_lite.rs | 88 +++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/codex-rs/core/src/tools/spec_plan.rs b/codex-rs/core/src/tools/spec_plan.rs index af7acf17a0..0928185dcc 100644 --- a/codex-rs/core/src/tools/spec_plan.rs +++ b/codex-rs/core/src/tools/spec_plan.rs @@ -395,7 +395,7 @@ fn image_generation_runtime_enabled(turn_context: &TurnContext) -> bool { } fn standalone_image_generation_model_visible(turn_context: &TurnContext) -> bool { - if !image_generation_runtime_enabled(turn_context) || !namespace_tools_enabled(turn_context) { + if !image_generation_tool_enabled(turn_context) || !namespace_tools_enabled(turn_context) { return false; } diff --git a/codex-rs/core/tests/suite/responses_lite.rs b/codex-rs/core/tests/suite/responses_lite.rs index b137d5bc73..d43bb23f86 100644 --- a/codex-rs/core/tests/suite/responses_lite.rs +++ b/codex-rs/core/tests/suite/responses_lite.rs @@ -161,6 +161,53 @@ async fn responses_lite_uses_standalone_web_search_and_image_generation() -> Res Ok(()) } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn responses_lite_hides_image_generation_when_feature_is_disabled() -> Result<()> { + skip_if_no_network!(Ok(())); + + let server = responses::start_mock_server().await; + let response_mock = responses::mount_sse_once( + &server, + responses::sse(vec![ + responses::ev_response_created("resp-1"), + responses::ev_completed("resp-1"), + ]), + ) + .await; + + let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); + let extensions = responses_extensions(&auth); + + let mut builder = test_codex() + .with_auth(auth) + .with_extensions(extensions) + .with_model_info_override("gpt-5.4", |model_info| { + model_info.use_responses_lite = true; + configure_image_capable_model(model_info); + }) + .with_config(|config| { + configure_responses_tools(config); + assert!(config.features.enable(Feature::ImageGenExt).is_ok()); + assert!(config.features.disable(Feature::ImageGeneration).is_ok()); + }); + let test = builder.build(&server).await?; + + test.submit_turn("Use standalone tools").await?; + + let request = response_mock.single_request(); + request + .tool_by_name("web", "run") + .context("disabling image generation should not hide standalone web search")?; + assert!(request.tool_by_name("image_gen", "imagegen").is_none()); + let body = request.body_json(); + let tools = body["tools"] + .as_array() + .context("Responses request tools should be an array")?; + assert!(!has_hosted_tool(tools, "image_generation")); + + Ok(()) +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn responses_lite_compact_request_uses_lite_transport_contract() -> Result<()> { skip_if_no_network!(Ok(())); @@ -289,3 +336,44 @@ async fn non_lite_uses_hosted_tools_when_standalone_features_are_disabled() -> R Ok(()) } + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn non_lite_uses_standalone_image_generation_when_features_are_enabled() -> Result<()> { + skip_if_no_network!(Ok(())); + + let server = responses::start_mock_server().await; + let response_mock = responses::mount_sse_once( + &server, + responses::sse(vec![ + responses::ev_response_created("resp-1"), + responses::ev_completed("resp-1"), + ]), + ) + .await; + + let auth = CodexAuth::create_dummy_chatgpt_auth_for_testing(); + let extensions = responses_extensions(&auth); + let mut builder = test_codex() + .with_auth(auth) + .with_extensions(extensions) + .with_model_info_override("gpt-5.4", configure_image_capable_model) + .with_config(|config| { + configure_responses_tools(config); + assert!(config.features.enable(Feature::ImageGenExt).is_ok()); + }); + let test = builder.build(&server).await?; + + test.submit_turn("Use standalone image generation").await?; + + let request = response_mock.single_request(); + request + .tool_by_name("image_gen", "imagegen") + .context("enabled image generation features should expose the standalone tool")?; + let body = request.body_json(); + let tools = body["tools"] + .as_array() + .context("Responses request tools should be an array")?; + assert!(!has_hosted_tool(tools, "image_generation")); + + Ok(()) +}