Add Code Mode files tool golden tests

This commit is contained in:
Liang-Ting Jiang
2026-05-13 10:42:00 -07:00
parent 5477a1771e
commit 97b8a13ace
2 changed files with 141 additions and 0 deletions

View File

@@ -2344,6 +2344,94 @@ fn code_mode_exec_description_omits_nested_tool_details_when_not_code_mode_only(
assert!(!description.contains("### `view_image`"));
}
#[test]
fn files_namespace_is_gated_by_experimental_supported_tool() {
let available_models = Vec::new();
let default_model_info = model_info();
let default_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &default_model_info,
available_models: &available_models,
features: &Features::with_defaults(),
image_generation_tool_auth_allowed: true,
web_search_mode: Some(WebSearchMode::Cached),
session_source: SessionSource::Cli,
permission_profile: &PermissionProfile::Disabled,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
});
let (default_tools, default_registry) = build_specs(
&default_config,
/*mcp_tools*/ None,
/*deferred_mcp_tools*/ None,
&[],
);
assert!(!default_tools.iter().any(|tool| tool.name() == "files"));
assert!(!default_registry.has_handler(&ToolName::namespaced("files", "materialize")));
let mut supported_model_info = model_info();
supported_model_info.experimental_supported_tools = vec!["code_mode_files".to_string()];
let supported_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &supported_model_info,
available_models: &available_models,
features: &Features::with_defaults(),
image_generation_tool_auth_allowed: true,
web_search_mode: Some(WebSearchMode::Cached),
session_source: SessionSource::Cli,
permission_profile: &PermissionProfile::Disabled,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
});
let (tools, registry) = build_specs(
&supported_config,
/*mcp_tools*/ None,
/*deferred_mcp_tools*/ None,
&[],
);
assert_eq!(
namespace_function_names(&tools, "files"),
vec!["copy", "export_for_tool", "materialize"]
);
assert!(registry.has_handler(&ToolName::namespaced("files", "materialize")));
assert!(registry.has_handler(&ToolName::namespaced("files", "copy")));
assert!(registry.has_handler(&ToolName::namespaced("files", "export_for_tool")));
}
#[test]
fn code_mode_exec_description_includes_gated_files_tools() {
let mut model_info = model_info();
model_info.experimental_supported_tools = vec!["code_mode_files".to_string()];
let mut features = Features::with_defaults();
features.enable(Feature::CodeMode);
features.enable(Feature::CodeModeOnly);
let available_models = Vec::new();
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
available_models: &available_models,
features: &features,
image_generation_tool_auth_allowed: true,
web_search_mode: Some(WebSearchMode::Cached),
session_source: SessionSource::Cli,
permission_profile: &PermissionProfile::Disabled,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
});
let (tools, _) = build_specs(
&tools_config,
/*mcp_tools*/ None,
/*deferred_mcp_tools*/ None,
&[],
);
let ToolSpec::Freeform(FreeformTool { description, .. }) = find_tool(&tools, "exec") else {
panic!("expected freeform tool");
};
assert!(description.contains("### `files_copy`"));
assert!(description.contains("### `files_export_for_tool`"));
assert!(description.contains("### `files_materialize`"));
assert!(description.contains("data URI"));
}
fn model_info() -> ModelInfo {
serde_json::from_value(json!({
"slug": "gpt-5-codex",

View File

@@ -1,9 +1,12 @@
use super::augment_tool_spec_for_code_mode;
use super::collect_code_mode_tool_definitions;
use super::tool_spec_to_code_mode_tool_definition;
use crate::AdditionalProperties;
use crate::FreeformTool;
use crate::FreeformToolFormat;
use crate::JsonSchema;
use crate::ResponsesApiNamespace;
use crate::ResponsesApiNamespaceTool;
use crate::ResponsesApiTool;
use crate::ToolName;
use crate::ToolSpec;
@@ -135,3 +138,53 @@ fn tool_spec_to_code_mode_tool_definition_skips_unsupported_variants() {
None
);
}
#[test]
fn namespace_tools_are_flattened_for_code_mode_runtime() {
let tools = collect_code_mode_tool_definitions([&ToolSpec::Namespace(ResponsesApiNamespace {
name: "files".to_string(),
description: "File tools".to_string(),
tools: vec![ResponsesApiNamespaceTool::Function(ResponsesApiTool {
name: "export_for_tool".to_string(),
description: "Export a file ref".to_string(),
strict: false,
defer_loading: None,
parameters: JsonSchema::object(
BTreeMap::from([(
"file_uri".to_string(),
JsonSchema::string(/*description*/ None),
)]),
Some(vec!["file_uri".to_string()]),
Some(AdditionalProperties::Boolean(false)),
),
output_schema: None,
})],
})]);
assert_eq!(
tools,
vec![codex_code_mode::ToolDefinition {
name: "files_export_for_tool".to_string(),
tool_name: ToolName::namespaced("files", "export_for_tool"),
description: r#"Export a file ref
exec tool declaration:
```ts
declare const tools: { files_export_for_tool(args: { file_uri: string; }): Promise<unknown>; };
```"#
.to_string(),
kind: codex_code_mode::CodeModeToolKind::Function,
input_schema: Some(json!({
"type": "object",
"properties": {
"file_uri": {
"type": "string"
}
},
"required": ["file_uri"],
"additionalProperties": false
})),
output_schema: None,
}]
);
}