mirror of
https://github.com/openai/codex.git
synced 2026-11-14 06:48:26 +00:00
[codex-apps] Filter optional file fields by tool schema (#31686)
## Summary Codex Apps file parameters are exposed to the model as local paths, uploaded at execution time, and rewritten into provided-file payloads before the MCP tool call. The rewrite currently includes the documented optional fields `mime_type` and `file_name` for every file parameter. Apps with strict schemas can reject those fields when they are not declared. ## Changes - Derive the supported optional file fields from each `openai/fileParams` parameter's raw input schema before replacing it with the model-visible local-path schema. - Always include `download_url` and `file_id`. - Include `mime_type` and `file_name` only when that specific file parameter's schema accepts them, including schemas that allow additional properties. - Handle scalar and array file parameters, including items-only arrays, composed schemas, and local JSON Schema references. - Preserve the existing restriction that only the host-owned Codex Apps MCP server can use this upload path. This supports tools with different file contracts in the same app: one parameter can accept the optional fields while another remains strict. ## Validation - `just test -p codex-mcp` - `just test -p codex-core mcp_openai_file` - `just test -p codex-core codex_apps_file_params_` - `just fix -p codex-mcp` - `just fix -p codex-core` - `just fmt` - `git diff --check` - Manually verified in the Codex Electron app that: - a strict file schema receives only `download_url` and `file_id` - a rich file schema also receives `mime_type` and `file_name` Related: #31330
This commit is contained in:
1 parent
6d3cde7fcd
commit
8347b8de21
21 files changed
+613
-233
No files matched your search
@@ -21,6 +21,7 @@ use std::time::Instant;
|
||||
use crate::codex_apps::normalize_codex_apps_callable_name;
|
||||
use crate::codex_apps::normalize_codex_apps_callable_namespace;
|
||||
use crate::codex_apps::normalize_codex_apps_tool_title;
|
||||
use crate::codex_apps::prepare_openai_file_params_for_model;
|
||||
use crate::codex_apps_cache::CodexAppsToolsCacheContext;
|
||||
use crate::codex_apps_cache::CodexAppsToolsFetchSource;
|
||||
use crate::codex_apps_cache::load_startup_cached_codex_apps_server_info;
|
||||
@@ -34,7 +35,6 @@ use crate::server::McpServerLaunch;
|
||||
use crate::tools::ToolFilter;
|
||||
use crate::tools::ToolInfo;
|
||||
use crate::tools::filter_tools;
|
||||
use crate::tools::tool_with_model_visible_input_schema;
|
||||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
use async_channel::Sender;
|
||||
@@ -620,7 +620,7 @@ fn prepare_codex_apps_tools_for_model(
|
||||
tool_plugin_provenance: &ToolPluginProvenance,
|
||||
) -> Vec<ToolInfo> {
|
||||
for tool in &mut tools {
|
||||
tool.tool = tool_with_model_visible_input_schema(&tool.tool);
|
||||
prepare_openai_file_params_for_model(tool);
|
||||
let plugin_names = match tool.connector_id.as_deref() {
|
||||
Some(connector_id) => {
|
||||
tool_plugin_provenance.plugin_display_names_for_connector_id(connector_id)
|
||||
@@ -733,6 +733,7 @@ fn codex_apps_tool_info_from_listed_tool(
|
||||
callable_namespace,
|
||||
namespace_description,
|
||||
tool: tool_def,
|
||||
openai_file_input_optional_fields: HashMap::new(),
|
||||
connector_id,
|
||||
connector_name,
|
||||
plugin_display_names: Vec::new(),
|
||||
@@ -756,6 +757,7 @@ fn regular_mcp_tool_info_from_listed_tool(
|
||||
callable_namespace: server_name.to_string(),
|
||||
namespace_description: server_instructions.map(str::to_string),
|
||||
tool: tool_def,
|
||||
openai_file_input_optional_fields: HashMap::new(),
|
||||
connector_id: None,
|
||||
connector_name: None,
|
||||
plugin_display_names: Vec::new(),
|
||||
@@ -1138,6 +1140,7 @@ mod tests {
|
||||
callable_namespace: "codex_apps__gmail".to_string(),
|
||||
namespace_description: Some("Mail connector".to_string()),
|
||||
tool: expected_tool,
|
||||
openai_file_input_optional_fields: HashMap::new(),
|
||||
connector_id: Some("connector_gmail".to_string()),
|
||||
connector_name: Some("Gmail".to_string()),
|
||||
plugin_display_names: Vec::new(),
|
||||
|
||||
Reference in new issue
Block a user