Skip to content

Add support for OpenAI verbosity parameter in Responses API #2493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Aug 13, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a8ab624
Add support for OpenAI verbosity parameter in Responses API
ryx2 Aug 10, 2025
12fdf3f
Address DouweM's review feedback on verbosity implementation
ryx2 Aug 12, 2025
7cc3180
✅ Successfully implement GPT-5 verbosity support with working test
ryx2 Aug 12, 2025
d37fc3e
Merge main into feat/openai-verbosity-support
ryx2 Aug 12, 2025
58edfb5
Add working VCR test for GPT-5 verbosity support
ryx2 Aug 13, 2025
2a99ebf
Fix OpenAI verbosity to work with JSON object/schema formats
ryx2 Aug 13, 2025
909cc16
Merge branch 'main' into feat/openai-verbosity-support
DouweM Aug 13, 2025
b09898b
Update pydantic_ai_slim/pydantic_ai/models/openai.py
ryx2 Aug 13, 2025
099edda
Clean up uv.lock to only include OpenAI 1.99.9 update
ryx2 Aug 13, 2025
da07a88
Merge branch 'main' into feat/openai-verbosity-support
ryx2 Aug 13, 2025
e71c25c
do the uv lock add only after make install
ryx2 Aug 13, 2025
7ef085a
do the uv lock add only after make install and deleting it first
ryx2 Aug 13, 2025
37149a9
updated my uv from 0.5.3 to 0.8.9
ryx2 Aug 13, 2025
5a4e09a
Merge branch 'main' into feat/openai-verbosity-support
DouweM Aug 13, 2025
ed2ce7f
Merge remote-tracking branch 'upstream/main' into feat/openai-verbosi…
ryx2 Aug 13, 2025
9267444
Use upstream pyproject.toml from main
ryx2 Aug 13, 2025
a7af490
Merge branch 'feat/openai-verbosity-support' of https://github.com/ry…
ryx2 Aug 13, 2025
487245c
revert pyproject change + newline lint issue
ryx2 Aug 13, 2025
1ab457c
Delete pydantic_ai_slim/pyproject.toml.main
ryx2 Aug 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions pydantic_ai_slim/pydantic_ai/models/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ class OpenAIResponsesModelSettings(OpenAIModelSettings, total=False):
middle of the conversation.
"""

openai_text_verbosity: Literal['low', 'medium', 'high']
"""Constrains the verbosity of the model's text response.
Lower values will result in more concise responses, while higher values will
result in more verbose responses. Currently supported values are `low`,
`medium`, and `high`.
"""


@dataclass(init=False)
class OpenAIModel(Model):
Expand Down Expand Up @@ -802,6 +810,12 @@ async def _responses_create(
model_request_parameters.output_mode == 'prompted' and self.profile.supports_json_object_output
): # pragma: no branch
text = {'format': {'type': 'json_object'}}

# Add verbosity setting to text config if specified
if verbosity := model_settings.get('openai_text_verbosity'):
if text is None:
text = {}
text['verbosity'] = verbosity

# Without this trick, we'd hit this error:
# > Response input messages must contain the word 'json' in some form to use 'text.format' of type 'json_object'.
Expand Down
10 changes: 10 additions & 0 deletions tests/models/test_openai_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1134,3 +1134,13 @@ async def get_user_country() -> str:
),
]
)


async def test_openai_responses_verbosity(allow_model_requests: None, openai_api_key: str):
"""Test that verbosity setting is properly passed to the OpenAI API"""
model = OpenAIResponsesModel('gpt-4o', provider=OpenAIProvider(api_key=openai_api_key))
agent = Agent(model=model, model_settings=OpenAIResponsesModelSettings(openai_text_verbosity='low'))
result = await agent.run('Explain quantum computing briefly.')
# The response should exist (we don't need to check exact content since it depends on the model)
assert isinstance(result.output, str)
assert len(result.output) > 0
Loading