Skip to content

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

Merged
jacobzhou-oai merged 5 commits into
mainfrom
codex/schema-aware-file-param-payloads
Jul 8, 2026
Merged

[codex-apps] Omit internal fields from file payloads#31330
jacobzhou-oai merged 5 commits into
mainfrom
codex/schema-aware-file-param-payloads

Conversation

@jacobzhou-oai

@jacobzhou-oai jacobzhou-oai commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@jacobzhou-oai jacobzhou-oai marked this pull request as ready for review July 7, 2026 15:56
@jacobzhou-oai jacobzhou-oai requested a review from a team as a code owner July 7, 2026 15:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea12126f62

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/core/src/mcp_openai_file.rs Outdated
Comment on lines +187 to +190
if optional_fields
.iter()
.any(|optional_field| optional_field == "mime_type")
&& let Some(mime_type) = uploaded.mime_type

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update integration tests for schema-aware file payloads

When a Codex Apps file param schema does not declare mime_type/file_name (the existing AppsTestServer fixture only declares file_id), this branch now sends only download_url and file_id, but core/tests/suite/openai_file_mcp.rs still expects uploaded_file() with mime_type, file_name, uri, and file_size_bytes for both the MCP call and the PostToolUse hook. That existing integration suite will fail once it reaches those assertions and no longer documents the intended user-facing payload shape, so please update the suite fixture/expectations alongside this payload change.

AGENTS.md reference: AGENTS.md:L114-L118

Useful? React with 👍 / 👎.

@jacobzhou-oai jacobzhou-oai force-pushed the codex/schema-aware-file-param-payloads branch from ea12126 to 8e0a76d Compare July 7, 2026 16:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00a35b1bf7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/codex-mcp/src/tools.rs Outdated
.get(keyword)
.and_then(JsonValue::as_array)
.is_some_and(|variants| {
variants.iter().any(|variant| {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict optional file fields to the matching union branch

For a file parameter schema that uses anyOf/oneOf to allow either a provided-file object or another image/file shape, this any marks mime_type or file_name as accepted when any variant declares it. If the provided-file variant is strict, e.g. {download_url,file_id} with additionalProperties:false, while another variant declares mime_type but also requires unrelated fields, the rewritten upload payload adds mime_type and then no union branch validates, so the Apps tool is rejected before execution. The optional-field scan should only include fields from a branch that can accept the uploaded provided-file payload, rather than any union branch.

Useful? React with 👍 / 👎.

Comment thread codex-rs/codex-mcp/src/tools.rs Outdated
Comment on lines +366 to +370
let first_segment = segments.next()?.replace("~1", "/").replace("~0", "~");
let mut referenced_schema = root_schema.get(&first_segment)?;

for segment in segments {
let segment = segment.replace("~1", "/").replace("~0", "~");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Decode URI-fragment refs before resolving

When an Apps schema uses a valid local $ref whose JSON Pointer fragment contains percent-encoded characters, for example #/$defs/Provided%20File for a $defs key named Provided File, this resolver splits and looks up the raw %20 text instead of URI-decoding the fragment first. In that case the optional file fields declared behind the ref are missed, so a strict tool that requires mime_type or file_name via such a ref still receives only download_url/file_id and can fail schema validation.

Useful? React with 👍 / 👎.

Comment thread codex-rs/codex-mcp/src/tools.rs Outdated
Comment on lines +275 to +278
let properties = tool
.input_schema
.get("properties")
.and_then(JsonValue::as_object);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Resolve root input-schema refs before reading properties

When an Apps tool defines its parameter object through a root $ref (for example inputSchema: { "$ref": "#/$defs/Params", "$defs": { ... } }) and declares openai/fileParams, this direct properties lookup returns None, so every file param is recorded with no accepted optional fields. A strict tool whose referenced file payload schema requires or accepts mime_type/file_name then receives only download_url/file_id, whereas the previous rewrite sent those fields, causing schema validation failures for otherwise valid referenced schemas.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31fe678000

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/codex-mcp/src/tools.rs Outdated
Comment on lines +324 to +328
if schema.get("type").and_then(JsonValue::as_str) == Some("array") {
if let Some(items) = schema.get("items") {
pending.push((items, true));
}
continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve nullable array file parameters as arrays

When a Codex Apps file parameter schema encodes a nullable array as type: ["array", "null"] with items (a standard JSON Schema form used elsewhere in this repo), this check does not recognize it as an array because as_str() returns None. openai_file_schema_info therefore leaves is_array false, and rewrite_input_property_schema_as_local_file_path masks the parameter as a single string even though the app will validate an array of uploaded-file objects, causing multi-file tools with this schema shape to receive scalar arguments and fail validation. Consider also treating a type array containing "array" (or the presence of items) as an array.

Useful? React with 👍 / 👎.

Comment thread codex-rs/codex-mcp/src/tools.rs Outdated
continue;
}

info.is_array |= inside_array;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep generic file arrays exposed as arrays

For a declared openai/fileParams argument whose schema is still an array but whose items are not one of the newly recognized canonical provided-file objects (for example a legacy/generic { "type": "array", "items": { "type": "object" } } schema), is_array stays false because it is only set after the item schema passes the canonical download_url/file_id property check. The subsequent masking then exposes the parameter as a single string instead of an array of paths, so the model will send a scalar while the app still validates an array; this regresses schemas the previous top-level type == "array" || items check handled.

Useful? React with 👍 / 👎.

Comment thread codex-rs/codex-mcp/src/tools.rs Outdated
Comment on lines +318 to +321
for keyword in ["anyOf", "oneOf", "allOf"] {
if let Some(variants) = schema.get(keyword).and_then(JsonValue::as_array) {
pending.extend(variants.iter().map(|variant| (variant, inside_array)));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don’t union optional fields across allOf branches

When a provided-file schema uses allOf, each branch must validate the same payload, but this traversal treats allOf the same as anyOf/oneOf and then ORs accepts_mime_type/accepts_file_name across the discovered branches. In a schema where one allOf branch is a strict {download_url,file_id} object (additionalProperties: false) and another branch mentions mime_type, Codex will now include mime_type, even though the strict branch rejects it before the app runs. For allOf, optional fields need to be intersected/merged with the constraints from every branch rather than accepted from any branch.

Useful? React with 👍 / 👎.

@jacobzhou-oai jacobzhou-oai changed the title [codex] Make app file payloads schema-aware [codex-apps] Omit internal fields from file payloads Jul 8, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 07ad70b1d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jacobzhou-oai

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Jul 8, 2026
@jacobzhou-oai jacobzhou-oai merged commit a09a7c4 into main Jul 8, 2026
35 of 36 checks passed
@jacobzhou-oai jacobzhou-oai deleted the codex/schema-aware-file-param-payloads branch July 8, 2026 23:04
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants