mirror of
https://github.com/openai/codex.git
synced 2026-04-28 00:25:56 +00:00
codex-tools: extract shared tool schema parsing (#15923)
## Why `parse_tool_input_schema` and the supporting `JsonSchema` model were living in `core/src/tools/spec.rs`, but they already serve callers outside `codex-core`. Keeping that shared schema parsing logic inside `codex-core` makes the crate boundary harder to reason about and works against the guidance in `AGENTS.md` to avoid growing `codex-core` when reusable code can live elsewhere. This change takes the first extraction step by moving the schema parsing primitive into its own crate while keeping the rest of the tool-spec assembly in `codex-core`. ## What changed - added a new `codex-tools` crate under `codex-rs/tools` - moved the shared tool input schema model and sanitizer/parser into `tools/src/json_schema.rs` - kept `tools/src/lib.rs` exports-only, with the module-level unit tests split into `json_schema_tests.rs` - updated `codex-core` to use `codex-tools::JsonSchema` and re-export `parse_tool_input_schema` - updated `codex-app-server` dynamic tool validation to depend on `codex-tools` directly instead of reaching through `codex-core` - wired the new crate into the Cargo workspace and Bazel build graph
This commit is contained in:
98
codex-rs/tools/src/json_schema_tests.rs
Normal file
98
codex-rs/tools/src/json_schema_tests.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use super::AdditionalProperties;
|
||||
use super::JsonSchema;
|
||||
use super::parse_tool_input_schema;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn parse_tool_input_schema_coerces_boolean_schemas() {
|
||||
let schema = parse_tool_input_schema(&serde_json::json!(true)).expect("parse schema");
|
||||
|
||||
assert_eq!(schema, JsonSchema::String { description: None });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_tool_input_schema_infers_object_shape_and_defaults_properties() {
|
||||
let schema = parse_tool_input_schema(&serde_json::json!({
|
||||
"properties": {
|
||||
"query": {"description": "search query"}
|
||||
}
|
||||
}))
|
||||
.expect("parse schema");
|
||||
|
||||
assert_eq!(
|
||||
schema,
|
||||
JsonSchema::Object {
|
||||
properties: BTreeMap::from([(
|
||||
"query".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("search query".to_string()),
|
||||
},
|
||||
)]),
|
||||
required: None,
|
||||
additional_properties: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_tool_input_schema_normalizes_integer_and_missing_array_items() {
|
||||
let schema = parse_tool_input_schema(&serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {"type": "integer"},
|
||||
"tags": {"type": "array"}
|
||||
}
|
||||
}))
|
||||
.expect("parse schema");
|
||||
|
||||
assert_eq!(
|
||||
schema,
|
||||
JsonSchema::Object {
|
||||
properties: BTreeMap::from([
|
||||
("page".to_string(), JsonSchema::Number { description: None },),
|
||||
(
|
||||
"tags".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: None,
|
||||
},
|
||||
),
|
||||
]),
|
||||
required: None,
|
||||
additional_properties: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_tool_input_schema_sanitizes_additional_properties_schema() {
|
||||
let schema = parse_tool_input_schema(&serde_json::json!({
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"required": ["value"],
|
||||
"properties": {
|
||||
"value": {"anyOf": [{"type": "string"}, {"type": "number"}]}
|
||||
}
|
||||
}
|
||||
}))
|
||||
.expect("parse schema");
|
||||
|
||||
assert_eq!(
|
||||
schema,
|
||||
JsonSchema::Object {
|
||||
properties: BTreeMap::new(),
|
||||
required: None,
|
||||
additional_properties: Some(AdditionalProperties::Schema(Box::new(
|
||||
JsonSchema::Object {
|
||||
properties: BTreeMap::from([(
|
||||
"value".to_string(),
|
||||
JsonSchema::String { description: None },
|
||||
)]),
|
||||
required: Some(vec!["value".to_string()]),
|
||||
additional_properties: None,
|
||||
},
|
||||
))),
|
||||
}
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user