Files
codex/codex-rs/tools/src/view_image_tests.rs
T
Michael Bolin 4e119a3b38 codex-tools: extract local host tool specs (#16138)
## Why

`core/src/tools/spec.rs` still bundled a set of pure local-host tool
builders with the orchestration that actually decides when those tools
are exposed and which handlers back them. That made `codex-core`
responsible for JSON/tool-shape construction that does not depend on
session state, and it kept the `codex-tools` migration from taking a
meaningfully larger bite out of `spec.rs`.

This PR moves that reusable spec-building layer into `codex-tools` while
leaving feature gating, handler registration, and runtime-coupled
descriptions in `codex-core`.

## What changed

- added `codex-rs/tools/src/local_tool.rs` for the pure builders for
`exec_command`, `write_stdin`, `shell`, `shell_command`, and
`request_permissions`
- added `codex-rs/tools/src/view_image.rs` for the `view_image` tool
spec and output schema so the extracted modules stay right-sized
- rewired `codex-rs/core/src/tools/spec.rs` to call those extracted
builders instead of constructing these specs inline
- kept the `request_permissions` description source in `codex-core`,
with `codex-tools` taking the description as input so the crate boundary
does not grow a dependency on handler/runtime code
- moved the direct constructor coverage for this slice from
`codex-rs/core/src/tools/spec_tests.rs` into
`codex-rs/tools/src/local_tool_tests.rs` and
`codex-rs/tools/src/view_image_tests.rs`
- updated `codex-rs/tools/README.md` to reflect that `codex-tools` now
owns this local-host spec layer

## Test plan

- `CARGO_TARGET_DIR=/tmp/codex-tools-local-host cargo test -p
codex-tools`
- `CARGO_TARGET_DIR=/tmp/codex-core-local-tools cargo test -p codex-core
--lib tools::spec::`
- `just argument-comment-lint`

## References

- #15923
- #15928
- #15944
- #15953
- #16031
- #16047
- #16129
- #16132
2026-03-28 16:33:58 -07:00

68 lines
2.9 KiB
Rust

use super::*;
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 <image ...> tags)."
.to_string(),
strict: false,
defer_loading: None,
parameters: JsonSchema::Object {
properties: BTreeMap::from([(
"path".to_string(),
JsonSchema::String {
description: Some("Local filesystem path to an image file".to_string()),
},
)]),
required: Some(vec!["path".to_string()]),
additional_properties: 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 <image ...> tags)."
.to_string(),
strict: false,
defer_loading: None,
parameters: JsonSchema::Object {
properties: BTreeMap::from([
(
"detail".to_string(),
JsonSchema::String {
description: 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 {
description: Some("Local filesystem path to an image file".to_string()),
},
),
]),
required: Some(vec!["path".to_string()]),
additional_properties: Some(false.into()),
},
output_schema: Some(view_image_output_schema()),
})
);
}