Skip to content

feat: add ResponseFormat support to call_model_input_filter (#3563)#3569

Closed
ylzn567 wants to merge 4 commits into
openai:mainfrom
ylzn567:main
Closed

feat: add ResponseFormat support to call_model_input_filter (#3563)#3569
ylzn567 wants to merge 4 commits into
openai:mainfrom
ylzn567:main

Conversation

@ylzn567
Copy link
Copy Markdown

@ylzn567 ylzn567 commented Jun 3, 2026

Closes #3563

Description

This PR adds response_format support to the call_model_input_filter callback in RunConfig. This allows developers to dynamically modify the expected response format (e.g., enforcing a strict JSON schema) immediately before the model is called.

Changes Made

  • Added response_format: ResponseFormat | None to the ModelInputData dataclass in src/agents/run_config.py.
  • Updated the maybe_filter_model_input function in src/agents/run_internal/turn_preparation.py to accept and pass the response_format.
  • Updated the run loop orchestration in src/agents/run_internal/run_loop.py to correctly inject model_settings.response_format into the filter during both streamed and non-streamed runs.

Next Steps

  • I'm opening this PR to get early feedback on the core implementation.
  • WIP: I am currently working on adding the contract tests requested in the issue to verify the durability around this runtime boundary. I will push those commits shortly when I have more time to dedicate to them.

(If you have a specific existing test fixture or file you recommend I use as a reference for testing this serialization/resume behavior, I'd appreciate the pointer!)

Copy link
Copy Markdown

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

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: c9ef7dc95d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/run_internal/run_loop.py Outdated
Comment thread src/agents/run_internal/run_loop.py Outdated
Copy link
Copy Markdown

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

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: 29b8bb6f51

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/run_internal/run_loop.py Outdated
context_wrapper=context_wrapper,
input_items=input,
system_instructions=system_prompt,
response_format=None,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass the filtered response format into the request

When a call_model_input_filter tries to inspect or replace ModelInputData.response_format, this call always seeds it with None, and the returned filtered.response_format is never used when model.get_response(..., output_schema=output_schema) is invoked later. In that scenario the new API is effectively inert: filters cannot see the current structured-output format and any strict JSON/schema format they return is dropped before the model request; the streamed path has the same response_format=None call site.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@codex address that feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copy link
Copy Markdown

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

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: 8f6f503e86

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/run_internal/run_loop.py Outdated
previous_response_id=previous_response_id,
conversation_id=conversation_id,
prompt=prompt_config,
response_format=filtered.response_format,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add response_format to model implementations

When any run reaches this call, model is an agents.models.interface.Model, but the interface and built-in implementations still define get_response(..., prompt=...) without a response_format keyword, so Python raises TypeError: unexpected keyword argument 'response_format' before the model request is made. The streamed path has the same new keyword at line 1489, so this needs the interface and every implementation updated (or the keyword removed until supported).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@codex address that feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ylzn567
Copy link
Copy Markdown
Author

ylzn567 commented Jun 3, 2026

Hi team! 👋
I've implemented the logic to pass and handle response_format via the call_model_input_filter. However, the Codex bot and I have hit a bit of a Catch-22:

  1. If I don't pass filtered.response_format to model.get_response(...), Codex flags it as an unused variable (since it drops before the model request).
  2. If I do pass it, Codex rightly points out that the base Model interface (src/agents/models/interface.py) and its implementations don't currently accept response_format as a kwarg, resulting in a TypeError.

To cleanly resolve this, the Model interface and all its concrete implementations (ChatCompletion, LiteLLM, Mocks, etc.) would need to be updated to accept this new parameter.

Since updating the entire model interface layer expands the scope of this PR significantly, I've temporarily reverted the kwarg injection. I would love your architectural guidance:
Would you like me to expand this PR to update interface.py and all underlying model wrappers? Or would you prefer to handle the interface expansion separately?

Copy link
Copy Markdown

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

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: 17b8225a26

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

context_wrapper=context_wrapper,
input_items=input,
system_instructions=system_prompt,
response_format=current_response_format,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply the filtered response format to the model call

When a call_model_input_filter returns a modified ModelInputData.response_format, the value is still discarded: this new argument only seeds the filter, while the subsequent model call continues to use the original output_schema and never reads filtered.response_format (the streamed path does the same). Fresh evidence in this revision is that the earlier crash was removed, but the returned response format remains unused, so filters cannot actually enforce or disable a JSON schema despite the new API field.

Useful? React with 👍 / 👎.

@ylzn567
Copy link
Copy Markdown
Author

ylzn567 commented Jun 3, 2026

I see @jordanchendev has already provided a complete solution along with the requested contract tests over in #3571!

Closing this PR to keep the tracker tidy. It was a great learning experience diving into the run loop and input filter architecture. Keep up the great work!

@ylzn567 ylzn567 closed this Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add custom ResponseFormat support in CallModelInputFilter callback

1 participant