diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index 7c3f6dd99a..58c1eb4d12 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -398,9 +398,6 @@ "guardian_approval": { "type": "boolean" }, - "image_detail_original": { - "type": "boolean" - }, "image_generation": { "type": "boolean" }, @@ -2254,9 +2251,6 @@ "guardian_approval": { "type": "boolean" }, - "image_detail_original": { - "type": "boolean" - }, "image_generation": { "type": "boolean" }, diff --git a/codex-rs/core/src/project_doc_tests.rs b/codex-rs/core/src/project_doc_tests.rs index 47deeff950..705801317e 100644 --- a/codex-rs/core/src/project_doc_tests.rs +++ b/codex-rs/core/src/project_doc_tests.rs @@ -228,25 +228,6 @@ async fn js_repl_tools_only_instructions_are_feature_gated() { assert_eq!(res, expected); } -#[tokio::test] -async fn js_repl_image_detail_original_does_not_change_instructions() { - let tmp = tempfile::tempdir().expect("tempdir"); - let mut cfg = make_config(&tmp, /*limit*/ 4096, /*instructions*/ None).await; - let mut features = cfg.features.get().clone(); - features - .enable(Feature::JsRepl) - .enable(Feature::ImageDetailOriginal); - cfg.features - .set(features) - .expect("test config should allow js_repl image detail settings"); - - let res = get_user_instructions(&cfg) - .await - .expect("js_repl instructions expected"); - let expected = "## JavaScript REPL (Node)\n- Use `js_repl` for Node-backed JavaScript with top-level await in a persistent kernel.\n- `js_repl` is a freeform/custom tool. Direct `js_repl` calls must send raw JavaScript tool input (optionally with first-line `// codex-js-repl: timeout_ms=15000`). Do not wrap code in JSON (for example `{\"code\":\"...\"}`), quotes, or markdown code fences.\n- Helpers: `codex.cwd`, `codex.homeDir`, `codex.tmpDir`, `codex.tool(name, args?)`, and `codex.emitImage(imageLike)`.\n- `codex.tool` executes a normal tool call and resolves to the raw tool output object. Use it for shell and non-shell tools alike. Nested tool outputs stay inside JavaScript unless you emit them explicitly.\n- `codex.emitImage(...)` adds one image to the outer `js_repl` function output each time you call it, so you can call it multiple times to emit multiple images. It accepts a data URL, a single `input_image` item, an object like `{ bytes, mimeType }`, or a raw tool response object with exactly one image and no text. It rejects mixed text-and-image content.\n- `codex.tool(...)` and `codex.emitImage(...)` keep stable helper identities across cells. Saved references and persisted objects can reuse them in later cells, but async callbacks that fire after a cell finishes still fail because no exec is active.\n- Request full-resolution image processing with `detail: \"original\"` only when the `view_image` tool schema includes a `detail` argument. The same availability applies to `codex.emitImage(...)`: if `view_image.detail` is present, you may also pass `detail: \"original\"` there. Use this when high-fidelity image perception or precise localization is needed, especially for CUA agents.\n- Example of sharing an in-memory Playwright screenshot: `await codex.emitImage({ bytes: await page.screenshot({ type: \"jpeg\", quality: 85 }), mimeType: \"image/jpeg\", detail: \"original\" })`.\n- Example of sharing a local image tool result: `await codex.emitImage(codex.tool(\"view_image\", { path: \"/absolute/path\", detail: \"original\" }))`.\n- When encoding an image to send with `codex.emitImage(...)` or `view_image`, prefer JPEG at about 85 quality when lossy compression is acceptable; use PNG when transparency or lossless detail matters. Smaller uploads are faster and less likely to hit size limits.\n- Top-level bindings persist across cells. If a cell throws, prior bindings remain available and bindings that finished initializing before the throw often remain usable in later cells. For code you plan to reuse across cells, prefer declaring or assigning it in direct top-level statements before operations that might throw. If you hit `SyntaxError: Identifier 'x' has already been declared`, first reuse the existing binding, reassign a previously declared `let`, or pick a new descriptive name. Use `{ ... }` only for a short temporary block when you specifically need local scratch names; do not wrap an entire cell in block scope if you want those names reusable later. Reset the kernel with `js_repl_reset` only when you need a clean state.\n- Top-level static import declarations (for example `import x from \"./file.js\"`) are currently unsupported in `js_repl`; use dynamic imports with `await import(\"pkg\")`, `await import(\"./file.js\")`, or `await import(\"/abs/path/file.mjs\")` instead. Imported local files must be ESM `.js`/`.mjs` files and run in the same REPL VM context. Bare package imports always resolve from REPL-global search roots (`CODEX_JS_REPL_NODE_MODULE_DIRS`, then cwd), not relative to the imported file location. Local files may statically import only other local relative/absolute/`file://` `.js`/`.mjs` files; package and builtin imports from local files must stay dynamic. `import.meta.resolve()` returns importable strings such as `file://...`, bare package names, and `node:...` specifiers. Local file modules reload between execs, while top-level bindings persist until `js_repl_reset`.\n- Avoid direct access to `process.stdout` / `process.stderr` / `process.stdin`; it can corrupt the JSON line protocol. Use `console.log`, `codex.tool(...)`, and `codex.emitImage(...)`."; - assert_eq!(res, expected); -} - /// When both system instructions *and* a project doc are present the two /// should be concatenated with the separator. #[tokio::test] diff --git a/codex-rs/core/src/tools/handlers/view_image.rs b/codex-rs/core/src/tools/handlers/view_image.rs index 1c9ddd3153..7f7448f250 100644 --- a/codex-rs/core/src/tools/handlers/view_image.rs +++ b/codex-rs/core/src/tools/handlers/view_image.rs @@ -125,8 +125,7 @@ impl ToolHandler for ViewImageHandler { })?; let event_path = abs_path.to_path_buf(); - let can_request_original_detail = - can_request_original_image_detail(turn.features.get(), &turn.model_info); + let can_request_original_detail = can_request_original_image_detail(&turn.model_info); let use_original_detail = can_request_original_detail && matches!(detail, Some(ViewImageDetail::Original)); let image_mode = if use_original_detail { diff --git a/codex-rs/core/src/tools/js_repl/mod.rs b/codex-rs/core/src/tools/js_repl/mod.rs index 9e2e88a5aa..b728009499 100644 --- a/codex-rs/core/src/tools/js_repl/mod.rs +++ b/codex-rs/core/src/tools/js_repl/mod.rs @@ -1714,7 +1714,7 @@ fn emitted_image_content_item( ) -> FunctionCallOutputContentItem { FunctionCallOutputContentItem::InputImage { image_url, - detail: normalize_output_image_detail(turn.features.get(), &turn.model_info, detail), + detail: normalize_output_image_detail(&turn.model_info, detail), } } diff --git a/codex-rs/core/src/tools/js_repl/mod_tests.rs b/codex-rs/core/src/tools/js_repl/mod_tests.rs index bdf6931330..6eb0552e34 100644 --- a/codex-rs/core/src/tools/js_repl/mod_tests.rs +++ b/codex-rs/core/src/tools/js_repl/mod_tests.rs @@ -2,7 +2,6 @@ use super::*; use crate::codex::make_session_and_context; use crate::codex::make_session_and_context_with_dynamic_tools_and_rx; use crate::turn_diff_tracker::TurnDiffTracker; -use codex_features::Feature; use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem; use codex_protocol::dynamic_tools::DynamicToolResponse; use codex_protocol::dynamic_tools::DynamicToolSpec; @@ -295,42 +294,8 @@ async fn emitted_image_content_item_drops_unsupported_explicit_detail() { } #[tokio::test] -async fn emitted_image_content_item_does_not_force_original_when_enabled() { +async fn emitted_image_content_item_allows_explicit_original_detail_when_supported() { let (_session, mut turn) = make_session_and_context().await; - Arc::make_mut(&mut turn.config) - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - turn.features - .enable(Feature::ImageDetailOriginal) - .expect("test turn features should allow feature update"); - turn.model_info.supports_image_detail_original = true; - - let content_item = emitted_image_content_item( - &turn, - "data:image/png;base64,AAA".to_string(), - /*detail*/ None, - ); - - assert_eq!( - content_item, - FunctionCallOutputContentItem::InputImage { - image_url: "data:image/png;base64,AAA".to_string(), - detail: None, - } - ); -} - -#[tokio::test] -async fn emitted_image_content_item_allows_explicit_original_detail_when_enabled() { - let (_session, mut turn) = make_session_and_context().await; - Arc::make_mut(&mut turn.config) - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - turn.features - .enable(Feature::ImageDetailOriginal) - .expect("test turn features should allow feature update"); turn.model_info.supports_image_detail_original = true; let content_item = emitted_image_content_item( @@ -349,7 +314,7 @@ async fn emitted_image_content_item_allows_explicit_original_detail_when_enabled } #[tokio::test] -async fn emitted_image_content_item_drops_explicit_original_detail_when_disabled() { +async fn emitted_image_content_item_drops_explicit_original_detail_when_unsupported() { let (_session, turn) = make_session_and_context().await; let content_item = emitted_image_content_item( diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index 0c65158d3c..76a70d5076 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -1832,7 +1832,6 @@ async fn code_mode_can_use_view_image_result_with_image_helper() -> Result<()> { .with_model("gpt-5.3-codex") .with_config(move |config| { let _ = config.features.enable(Feature::CodeMode); - let _ = config.features.enable(Feature::ImageDetailOriginal); }); let test = builder.build(&server).await?; diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index c2dab9d178..c7b9c02466 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -3,7 +3,6 @@ use base64::Engine; use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use codex_exec_server::CreateDirectoryOptions; -use codex_features::Feature; use codex_login::CodexAuth; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::openai_models::ConfigShellToolType; @@ -361,14 +360,7 @@ async fn view_image_tool_can_preserve_original_resolution_when_requested_on_gpt5 skip_if_no_network!(Ok(())); let server = start_mock_server().await; - let mut builder = test_codex() - .with_model("gpt-5.3-codex") - .with_config(|config| { - config - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - }); + let mut builder = test_codex().with_model("gpt-5.3-codex"); let test = builder.build_remote_aware(&server).await?; let TestCodex { codex, @@ -469,14 +461,7 @@ async fn view_image_tool_errors_clearly_for_unsupported_detail_values() -> anyho skip_if_no_network!(Ok(())); let server = start_mock_server().await; - let mut builder = test_codex() - .with_model("gpt-5.3-codex") - .with_config(|config| { - config - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - }); + let mut builder = test_codex().with_model("gpt-5.3-codex"); let test = builder.build_remote_aware(&server).await?; let TestCodex { codex, @@ -559,14 +544,7 @@ async fn view_image_tool_treats_null_detail_as_omitted() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; - let mut builder = test_codex() - .with_model("gpt-5.3-codex") - .with_config(|config| { - config - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - }); + let mut builder = test_codex().with_model("gpt-5.3-codex"); let test = builder.build_remote_aware(&server).await?; let TestCodex { codex, @@ -661,12 +639,7 @@ async fn view_image_tool_resizes_when_model_lacks_original_detail_support() -> a skip_if_no_network!(Ok(())); let server = start_mock_server().await; - let mut builder = test_codex().with_model("gpt-5.2").with_config(|config| { - config - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - }); + let mut builder = test_codex().with_model("gpt-5.2"); let test = builder.build_remote_aware(&server).await?; let TestCodex { codex, @@ -765,19 +738,12 @@ async fn view_image_tool_resizes_when_model_lacks_original_detail_support() -> a } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn view_image_tool_does_not_force_original_resolution_with_capability_feature_only() +async fn view_image_tool_does_not_force_original_resolution_with_capability_only() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; - let mut builder = test_codex() - .with_model("gpt-5.3-codex") - .with_config(|config| { - config - .features - .enable(Feature::ImageDetailOriginal) - .expect("test config should allow feature update"); - }); + let mut builder = test_codex().with_model("gpt-5.3-codex"); let test = builder.build_remote_aware(&server).await?; let TestCodex { codex, @@ -1533,3 +1499,4 @@ async fn replaces_invalid_local_image_after_bad_request() -> anyhow::Result<()> Ok(()) } +use codex_features::Feature; diff --git a/codex-rs/features/src/lib.rs b/codex-rs/features/src/lib.rs index 7e7d3b5dc8..aa32a45718 100644 --- a/codex-rs/features/src/lib.rs +++ b/codex-rs/features/src/lib.rs @@ -134,8 +134,6 @@ pub enum Feature { Telepathy, /// Append additional AGENTS.md guidance to user instructions. ChildAgentsMd, - /// Allow the model to request `detail: "original"` image outputs on supported models. - ImageDetailOriginal, /// Compress request bodies (zstd) when sending streaming requests to codex-backend. EnableRequestCompression, /// Enable collab tools. @@ -363,6 +361,9 @@ impl Features { "tui_app_server" => { continue; } + "image_detail_original" => { + continue; + } _ => {} } match feature_for_key(k) { @@ -683,16 +684,6 @@ pub const FEATURES: &[FeatureSpec] = &[ stage: Stage::UnderDevelopment, default_enabled: false, }, - FeatureSpec { - id: Feature::ImageDetailOriginal, - key: "image_detail_original", - stage: Stage::Experimental { - name: "Original image detail", - menu_description: "Let the model inspect tool-emitted images at full resolution on supported models instead of a resized approximation. This affects tool-emitted images such as those produced by `view_image`, not images attached directly in the UI. It is particularly important for localization and precise UI targeting, for reading small text, and for reasoning about precise layout.", - announcement: "NEW: Original image detail is now available in /experimental. Enable it to let tools request full-resolution image detail on supported models for CUA and localization tasks.", - }, - default_enabled: false, - }, FeatureSpec { id: Feature::ApplyPatchFreeform, key: "apply_patch_freeform", diff --git a/codex-rs/features/src/tests.rs b/codex-rs/features/src/tests.rs index bc357a7fb4..3ecab0997c 100644 --- a/codex-rs/features/src/tests.rs +++ b/codex-rs/features/src/tests.rs @@ -169,18 +169,6 @@ fn use_agent_identity_is_under_development() { assert_eq!(Feature::UseAgentIdentity.default_enabled(), false); } -#[test] -fn image_detail_original_feature_is_experimental_and_user_toggleable() { - let stage = Feature::ImageDetailOriginal.stage(); - - assert!(matches!(stage, Stage::Experimental { .. })); - assert_eq!( - stage.experimental_menu_name(), - Some("Original image detail") - ); - assert_eq!(Feature::ImageDetailOriginal.default_enabled(), false); -} - #[test] fn collab_is_legacy_alias_for_multi_agent() { assert_eq!(feature_for_key("multi_agent"), Some(Feature::Collab)); @@ -263,6 +251,25 @@ fn from_sources_applies_base_profile_and_overrides() { assert_eq!(features.enabled(Feature::WebSearchRequest), false); } +#[test] +fn from_sources_ignores_removed_image_detail_original_feature_key() { + let features_toml = FeaturesToml::from(BTreeMap::from([( + "image_detail_original".to_string(), + true, + )])); + + let features = Features::from_sources( + FeatureConfigSource { + features: Some(&features_toml), + ..Default::default() + }, + FeatureConfigSource::default(), + FeatureOverrides::default(), + ); + + assert_eq!(features, Features::with_defaults()); +} + #[test] fn multi_agent_v2_feature_config_deserializes_boolean_toggle() { let features: FeaturesToml = toml::from_str( diff --git a/codex-rs/tools/src/image_detail.rs b/codex-rs/tools/src/image_detail.rs index 93c11aee82..94639e61f9 100644 --- a/codex-rs/tools/src/image_detail.rs +++ b/codex-rs/tools/src/image_detail.rs @@ -1,19 +1,16 @@ -use codex_features::Feature; -use codex_features::Features; use codex_protocol::models::ImageDetail; use codex_protocol::openai_models::ModelInfo; -pub fn can_request_original_image_detail(features: &Features, model_info: &ModelInfo) -> bool { - model_info.supports_image_detail_original && features.enabled(Feature::ImageDetailOriginal) +pub fn can_request_original_image_detail(model_info: &ModelInfo) -> bool { + model_info.supports_image_detail_original } pub fn normalize_output_image_detail( - features: &Features, model_info: &ModelInfo, detail: Option, ) -> Option { match detail { - Some(ImageDetail::Original) if can_request_original_image_detail(features, model_info) => { + Some(ImageDetail::Original) if can_request_original_image_detail(model_info) => { Some(ImageDetail::Original) } Some(ImageDetail::Original) | Some(_) | None => None, diff --git a/codex-rs/tools/src/image_detail_tests.rs b/codex-rs/tools/src/image_detail_tests.rs index cfaeb7fb26..35d666149f 100644 --- a/codex-rs/tools/src/image_detail_tests.rs +++ b/codex-rs/tools/src/image_detail_tests.rs @@ -1,6 +1,4 @@ use super::*; -use codex_features::Feature; -use codex_features::Features; use codex_protocol::models::ImageDetail; use codex_protocol::openai_models::ModelInfo; use pretty_assertions::assert_eq; @@ -42,37 +40,26 @@ fn model_info() -> ModelInfo { } #[test] -fn image_detail_original_feature_enables_explicit_original_without_force() { +fn explicit_original_is_allowed_when_model_supports_it() { let model_info = model_info(); - let mut features = Features::with_defaults(); - features.enable(Feature::ImageDetailOriginal); - assert!(can_request_original_image_detail(&features, &model_info)); + assert!(can_request_original_image_detail(&model_info)); assert_eq!( - normalize_output_image_detail(&features, &model_info, Some(ImageDetail::Original)), + normalize_output_image_detail(&model_info, Some(ImageDetail::Original)), Some(ImageDetail::Original) ); assert_eq!( - normalize_output_image_detail(&features, &model_info, /*detail*/ None), + normalize_output_image_detail(&model_info, /*detail*/ None), None ); } #[test] -fn explicit_original_is_dropped_without_feature_or_model_support() { +fn explicit_original_is_dropped_without_model_support() { let mut model_info = model_info(); - let features = Features::with_defaults(); - - assert_eq!( - normalize_output_image_detail(&features, &model_info, Some(ImageDetail::Original)), - None - ); - - let mut features = Features::with_defaults(); - features.enable(Feature::ImageDetailOriginal); model_info.supports_image_detail_original = false; assert_eq!( - normalize_output_image_detail(&features, &model_info, Some(ImageDetail::Original)), + normalize_output_image_detail(&model_info, Some(ImageDetail::Original)), None ); } @@ -80,11 +67,9 @@ fn explicit_original_is_dropped_without_feature_or_model_support() { #[test] fn unsupported_non_original_detail_is_dropped() { let model_info = model_info(); - let mut features = Features::with_defaults(); - features.enable(Feature::ImageDetailOriginal); assert_eq!( - normalize_output_image_detail(&features, &model_info, Some(ImageDetail::Low)), + normalize_output_image_detail(&model_info, Some(ImageDetail::Low)), None ); } diff --git a/codex-rs/tools/src/tool_config.rs b/codex-rs/tools/src/tool_config.rs index 912542d9f6..20c812ce96 100644 --- a/codex-rs/tools/src/tool_config.rs +++ b/codex-rs/tools/src/tool_config.rs @@ -153,7 +153,7 @@ impl ToolsConfig { let include_tool_suggest = features.enabled(Feature::ToolSuggest) && features.enabled(Feature::Apps) && features.enabled(Feature::Plugins); - let include_original_image_detail = can_request_original_image_detail(features, model_info); + let include_original_image_detail = can_request_original_image_detail(model_info); // API-key auth bypasses Codex backend entitlement/tool normalization, so // callers must confirm ChatGPT auth before exposing the built-in tool. let include_image_gen_tool = *image_generation_tool_auth_allowed diff --git a/codex-rs/tools/src/tool_registry_plan_tests.rs b/codex-rs/tools/src/tool_registry_plan_tests.rs index 9da58849c1..69b8b55b54 100644 --- a/codex-rs/tools/src/tool_registry_plan_tests.rs +++ b/codex-rs/tools/src/tool_registry_plan_tests.rs @@ -362,9 +362,9 @@ fn test_build_specs_enable_fanout_enables_agent_jobs_and_collab_tools() { } #[test] -fn view_image_tool_omits_detail_without_original_detail_feature() { +fn view_image_tool_omits_detail_without_original_detail_support() { let mut model_info = model_info(); - model_info.supports_image_detail_original = true; + model_info.supports_image_detail_original = false; let features = Features::with_defaults(); let available_models = Vec::new(); let tools_config = ToolsConfig::new(&ToolsConfigParams { @@ -392,11 +392,10 @@ fn view_image_tool_omits_detail_without_original_detail_feature() { } #[test] -fn view_image_tool_includes_detail_with_original_detail_feature() { +fn view_image_tool_includes_detail_with_original_detail_support() { let mut model_info = model_info(); model_info.supports_image_detail_original = true; - let mut features = Features::with_defaults(); - features.enable(Feature::ImageDetailOriginal); + let features = Features::with_defaults(); let available_models = Vec::new(); let tools_config = ToolsConfig::new(&ToolsConfigParams { model_info: &model_info, diff --git a/codex-rs/tools/src/view_image.rs b/codex-rs/tools/src/view_image.rs index 5d591a339f..1d77ceadf3 100644 --- a/codex-rs/tools/src/view_image.rs +++ b/codex-rs/tools/src/view_image.rs @@ -53,7 +53,3 @@ fn view_image_output_schema() -> Value { "additionalProperties": false }) } - -#[cfg(test)] -#[path = "view_image_tests.rs"] -mod tests; diff --git a/codex-rs/tools/src/view_image_tests.rs b/codex-rs/tools/src/view_image_tests.rs deleted file mode 100644 index 3d67829657..0000000000 --- a/codex-rs/tools/src/view_image_tests.rs +++ /dev/null @@ -1,54 +0,0 @@ -use super::*; -use crate::JsonSchema; -use pretty_assertions::assert_eq; -use std::collections::BTreeMap; - -#[test] -fn view_image_tool_omits_detail_without_original_detail_feature() { - assert_eq!( - create_view_image_tool(ViewImageToolOptions { - can_request_original_image_detail: false, - }), - ToolSpec::Function(ResponsesApiTool { - name: "view_image".to_string(), - description: "View a local image from the filesystem (only use if given a full filepath by the user, and the image isn't already attached to the thread context within tags)." - .to_string(), - strict: false, - defer_loading: None, - parameters: JsonSchema::object(BTreeMap::from([( - "path".to_string(), - JsonSchema::string(Some("Local filesystem path to an image file".to_string()),), - )]), Some(vec!["path".to_string()]), Some(false.into())), - output_schema: Some(view_image_output_schema()), - }) - ); -} - -#[test] -fn view_image_tool_includes_detail_with_original_detail_feature() { - assert_eq!( - create_view_image_tool(ViewImageToolOptions { - can_request_original_image_detail: true, - }), - ToolSpec::Function(ResponsesApiTool { - name: "view_image".to_string(), - description: "View a local image from the filesystem (only use if given a full filepath by the user, and the image isn't already attached to the thread context within tags)." - .to_string(), - strict: false, - defer_loading: None, - parameters: JsonSchema::object(BTreeMap::from([ - ( - "detail".to_string(), - JsonSchema::string(Some( - "Optional detail override. The only supported value is `original`; omit this field for default resized behavior. Use `original` to preserve the file's original resolution instead of resizing to fit. This is important when high-fidelity image perception or precise localization is needed, especially for CUA agents.".to_string(), - ),), - ), - ( - "path".to_string(), - JsonSchema::string(Some("Local filesystem path to an image file".to_string()),), - ), - ]), Some(vec!["path".to_string()]), Some(false.into())), - output_schema: Some(view_image_output_schema()), - }) - ); -}