Files
codex/codex-rs/tools/src/mcp_tool_tests.rs
Vivian Fang ea516f9a40 Support anyOf and enum in JsonSchema (#16875)
This brings us into better alignment with the JSON schema subset that is
supported in
<https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas>,
and also allows us to render richer function signatures in code mode
(e.g., anyOf{null, OtherObjectType})
2026-04-08 01:07:55 -07:00

127 lines
3.6 KiB
Rust

use super::mcp_call_tool_result_output_schema;
use super::parse_mcp_tool;
use crate::JsonSchema;
use crate::ToolDefinition;
use pretty_assertions::assert_eq;
use std::collections::BTreeMap;
fn mcp_tool(name: &str, description: &str, input_schema: serde_json::Value) -> rmcp::model::Tool {
rmcp::model::Tool {
name: name.to_string().into(),
title: None,
description: Some(description.to_string().into()),
input_schema: std::sync::Arc::new(rmcp::model::object(input_schema)),
output_schema: None,
annotations: None,
execution: None,
icons: None,
meta: None,
}
}
#[test]
fn parse_mcp_tool_inserts_empty_properties() {
let tool = mcp_tool(
"no_props",
"No properties",
serde_json::json!({
"type": "object"
}),
);
assert_eq!(
parse_mcp_tool(&tool).expect("parse MCP tool"),
ToolDefinition {
name: "no_props".to_string(),
description: "No properties".to_string(),
input_schema: JsonSchema::object(
BTreeMap::new(),
/*required*/ None,
/*additional_properties*/ None
),
output_schema: Some(mcp_call_tool_result_output_schema(serde_json::json!({}))),
defer_loading: false,
}
);
}
#[test]
fn parse_mcp_tool_preserves_top_level_output_schema() {
let mut tool = mcp_tool(
"with_output",
"Has output schema",
serde_json::json!({
"type": "object"
}),
);
tool.output_schema = Some(std::sync::Arc::new(rmcp::model::object(
serde_json::json!({
"properties": {
"result": {
"properties": {
"nested": {}
}
}
},
"required": ["result"]
}),
)));
assert_eq!(
parse_mcp_tool(&tool).expect("parse MCP tool"),
ToolDefinition {
name: "with_output".to_string(),
description: "Has output schema".to_string(),
input_schema: JsonSchema::object(
BTreeMap::new(),
/*required*/ None,
/*additional_properties*/ None
),
output_schema: Some(mcp_call_tool_result_output_schema(serde_json::json!({
"properties": {
"result": {
"properties": {
"nested": {}
}
}
},
"required": ["result"]
}))),
defer_loading: false,
}
);
}
#[test]
fn parse_mcp_tool_preserves_output_schema_without_inferred_type() {
let mut tool = mcp_tool(
"with_enum_output",
"Has enum output schema",
serde_json::json!({
"type": "object"
}),
);
tool.output_schema = Some(std::sync::Arc::new(rmcp::model::object(
serde_json::json!({
"enum": ["ok", "error"]
}),
)));
assert_eq!(
parse_mcp_tool(&tool).expect("parse MCP tool"),
ToolDefinition {
name: "with_enum_output".to_string(),
description: "Has enum output schema".to_string(),
input_schema: JsonSchema::object(
BTreeMap::new(),
/*required*/ None,
/*additional_properties*/ None
),
output_schema: Some(mcp_call_tool_result_output_schema(serde_json::json!({
"enum": ["ok", "error"]
}))),
defer_loading: false,
}
);
}