[codex-apps] Omit internal fields from file payloads (#31330)

## 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 forwards two internal upload fields, `uri` and
`file_size_bytes`, even though they are not part of the documented app
file-reference shape. Strict app schemas can reject those extra fields
before execution.

## Changes

- Stop copying `uri` and `file_size_bytes` into app-facing MCP
arguments.
- Keep the internal `UploadedOpenAiFile` result unchanged.
- Preserve the existing `download_url`, `file_id`, `mime_type`, and
`file_name` behavior for scalar and array file inputs.
- Verify the MCP invocation and post-tool hook receive exactly the
documented four-field payload against an `additionalProperties: false`
schema.

This intentionally does not add schema inspection or change how
`openai/fileParams` names are discovered.

## Validation

- `just test -p codex-core mcp_openai_file` (6 passed)
- `just test -p codex-core codex_apps_file_params_` (2 passed)
- `just fix -p codex-core`
- `just fmt`
- `git diff --check`
This commit is contained in:
jacobzhou-oai
2026-07-08 16:04:30 -07:00
committed by GitHub
parent 4e270ddec4
commit a09a7c41d8
3 changed files with 9 additions and 20 deletions
-10
View File
@@ -173,8 +173,6 @@ async fn build_uploaded_argument_value(
"file_id": uploaded.file_id,
"mime_type": uploaded.mime_type,
"file_name": uploaded.file_name,
"uri": uploaded.uri,
"file_size_bytes": uploaded.file_size_bytes,
}))
}
@@ -300,8 +298,6 @@ mod tests {
"file_id": "file_123",
"mime_type": "text/csv",
"file_name": "file_report.csv",
"uri": "sediment://file_123",
"file_size_bytes": 5,
})
);
}
@@ -404,8 +400,6 @@ mod tests {
"file_id": "file_123",
"mime_type": "text/csv",
"file_name": "file_report.csv",
"uri": "sediment://file_123",
"file_size_bytes": 5,
}))
);
}
@@ -519,16 +513,12 @@ mod tests {
"file_id": "file_1",
"mime_type": "text/csv",
"file_name": "one.csv",
"uri": "sediment://file_1",
"file_size_bytes": 3,
},
{
"download_url": format!("{}/download/file_2", server.uri()),
"file_id": "file_2",
"mime_type": "text/csv",
"file_name": "two.csv",
"uri": "sediment://file_2",
"file_size_bytes": 3,
}
]))
);
@@ -553,9 +553,13 @@ impl Respond for CodexAppsJsonRpcResponder {
"type": "object",
"description": "Document file payload.",
"properties": {
"file_id": { "type": "string" }
"download_url": { "type": "string" },
"file_id": { "type": "string" },
"mime_type": { "type": "string" },
"file_name": { "type": "string" }
},
"required": ["file_id"]
"required": ["download_url", "file_id"],
"additionalProperties": false
}
},
"required": ["file"],
+3 -8
View File
@@ -91,14 +91,12 @@ fn read_post_tool_use_hook_inputs(home: &Path) -> Result<Vec<Value>> {
.collect()
}
fn uploaded_file(server: &MockServer, file_size_bytes: u64) -> Value {
fn uploaded_file(server: &MockServer) -> Value {
json!({
"download_url": format!("{}/download/file_123", server.uri()),
"file_id": "file_123",
"mime_type": "text/plain",
"file_name": "report.txt",
"uri": "sediment://file_123",
"file_size_bytes": file_size_bytes,
})
}
@@ -230,7 +228,7 @@ async fn codex_apps_file_params_upload_environment_files_before_mcp_tool_call()
assert_eq!(
apps_tool_call.pointer("/params/arguments/file"),
Some(&uploaded_file(&server, STREAMED_FILE_SIZE as u64))
Some(&uploaded_file(&server))
);
assert_eq!(
apps_tool_call.pointer("/params/_meta/_codex_apps"),
@@ -267,10 +265,7 @@ async fn codex_apps_file_params_pass_uploaded_file_to_post_tool_use_hook() -> Re
let hook_inputs = read_post_tool_use_hook_inputs(test.codex_home_path())?;
assert_eq!(hook_inputs.len(), 1);
assert_eq!(
hook_inputs[0]["tool_input"]["file"],
uploaded_file(&server, /*file_size_bytes*/ 11)
);
assert_eq!(hook_inputs[0]["tool_input"]["file"], uploaded_file(&server));
server.verify().await;
Ok(())