Skip to content

Commit 1d3bb01

Browse files
authored
Add OpenAIModelProfile.openai_responses_requires_function_call_status_none flag to satisfy vLLM Responses API (#3246)
1 parent f96dfe4 commit 1d3bb01

File tree

5 files changed

+366
-31
lines changed

5 files changed

+366
-31
lines changed

pydantic_ai_slim/pydantic_ai/models/openai.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,8 @@ async def _map_messages( # noqa: C901
14311431
call_id=call_id,
14321432
type='function_call',
14331433
)
1434+
if profile.openai_responses_requires_function_call_status_none:
1435+
param['status'] = None # type: ignore[reportGeneralTypeIssues]
14341436
if id and send_item_ids: # pragma: no branch
14351437
param['id'] = id
14361438
openai_messages.append(param)

pydantic_ai_slim/pydantic_ai/profiles/openai.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ class OpenAIModelProfile(ModelProfile):
4444
openai_supports_encrypted_reasoning_content: bool = False
4545
"""Whether the model supports including encrypted reasoning content in the response."""
4646

47+
openai_responses_requires_function_call_status_none: bool = False
48+
"""Whether the Responses API requires the `status` field on function tool calls to be `None`.
49+
50+
This is required by vLLM Responses API versions before https://github.com/vllm-project/vllm/pull/26706.
51+
See https://github.com/pydantic/pydantic-ai/issues/3245 for more details.
52+
"""
53+
4754
def __post_init__(self): # pragma: no cover
4855
if not self.openai_supports_sampling_settings:
4956
warnings.warn(

tests/models/cassettes/test_openai_responses/test_openai_responses_model_simple_response_with_tool_call.yaml

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interactions:
88
connection:
99
- keep-alive
1010
content-length:
11-
- '338'
11+
- '337'
1212
content-type:
1313
- application/json
1414
host:
@@ -18,11 +18,11 @@ interactions:
1818
input:
1919
- content: What is the capital of PotatoLand?
2020
role: user
21-
instructions: ''
2221
model: gpt-4o
22+
stream: false
2323
tool_choice: auto
2424
tools:
25-
- description: ''
25+
- description: null
2626
name: get_capital
2727
parameters:
2828
additionalProperties: false
@@ -42,47 +42,57 @@ interactions:
4242
connection:
4343
- keep-alive
4444
content-length:
45-
- '1497'
45+
- '1720'
4646
content-type:
4747
- application/json
4848
openai-organization:
4949
- pydantic-28gund
5050
openai-processing-ms:
51-
- '666'
51+
- '1811'
52+
openai-project:
53+
- proj_dKobscVY9YJxeEaDJen54e3d
5254
openai-version:
5355
- '2020-10-01'
5456
strict-transport-security:
5557
- max-age=31536000; includeSubDomains; preload
5658
transfer-encoding:
5759
- chunked
5860
parsed_body:
59-
created_at: 1743075630
61+
background: false
62+
billing:
63+
payer: developer
64+
created_at: 1761323546
6065
error: null
61-
id: resp_67e5392eae34819184408ee7e23f50160aa13be256b050b4
66+
id: resp_04907f5d3de791830068fbaa19bb908195a91378279dba0f14
6267
incomplete_details: null
63-
instructions: ''
68+
instructions: null
6469
max_output_tokens: null
70+
max_tool_calls: null
6571
metadata: {}
6672
model: gpt-4o-2024-08-06
6773
object: response
6874
output:
6975
- arguments: '{"country":"PotatoLand"}'
70-
call_id: call_Zmx4ZiPQOvoNEhLgG16TO3nx
71-
id: fc_67e5392f33ac8191b215eeff4f9931f80aa13be256b050b4
76+
call_id: call_YfwRsW8sUxDKipwyhWTzOXCA
77+
id: fc_04907f5d3de791830068fbaa1b310c81958dc9c508e878c632
7278
name: get_capital
7379
status: completed
7480
type: function_call
7581
parallel_tool_calls: true
7682
previous_response_id: null
83+
prompt_cache_key: null
7784
reasoning:
7885
effort: null
79-
generate_summary: null
86+
summary: null
87+
safety_identifier: null
88+
service_tier: default
8089
status: completed
8190
store: true
8291
temperature: 1.0
8392
text:
8493
format:
8594
type: text
95+
verbosity: medium
8696
tool_choice: auto
8797
tools:
8898
- description: null
@@ -97,16 +107,17 @@ interactions:
97107
type: object
98108
strict: true
99109
type: function
110+
top_logprobs: 0
100111
top_p: 1.0
101112
truncation: disabled
102113
usage:
103-
input_tokens: 256
114+
input_tokens: 40
104115
input_tokens_details:
105116
cached_tokens: 0
106117
output_tokens: 18
107118
output_tokens_details:
108119
reasoning_tokens: 0
109-
total_tokens: 274
120+
total_tokens: 58
110121
user: null
111122
status:
112123
code: 200
@@ -120,33 +131,32 @@ interactions:
120131
connection:
121132
- keep-alive
122133
content-length:
123-
- '600'
134+
- '579'
124135
content-type:
125136
- application/json
126137
cookie:
127-
- __cf_bm=vVsJhB9A9X9_43ZZ4_DPKFw_dO0SSxBWEhx4UiGncwQ-1743075631-1.0.1.1-N3mdrI4LFgBBnd_XI5x81Q5KKuykqiNo8wFt1XpgnPkVX0ISneJo_Yh1B3ZyfLeI5LaMdhMxhGB6wOfgrg4pP9f33KlF4C8grewNF05MpKw;
128-
_cfuvid=vB6MpPuauumuSrL6beYNRLXeNQt2_XZpKzom2c97AFI-1743075631374-0.0.1.1-604800000
138+
- __cf_bm=g29aPgrRIxmp3X5o6PZW9E8aKljsJ3_YKN58sMhqjnI-1761323547-1.0.1.1-Uj.mPGHnvAjpHojYAfG.QReYxHtLCz0jBoPrirBGA48A.LawB_Afgv0C8s0DC2TIU2y6zbyq4bA1moTVcNApxaq4NaLqfKpLe2hQBB_xM.M;
139+
_cfuvid=kiKLNQ6S_H_I6dKfHm0bpQwt35G4FrXx6u4P3LxaXIQ-1761323547535-0.0.1.1-604800000
129140
host:
130141
- api.openai.com
131142
method: POST
132143
parsed_body:
133144
input:
134145
- content: What is the capital of PotatoLand?
135146
role: user
136-
- content: ''
137-
role: assistant
138147
- arguments: '{"country":"PotatoLand"}'
139-
call_id: call_Zmx4ZiPQOvoNEhLgG16TO3nx
148+
call_id: call_YfwRsW8sUxDKipwyhWTzOXCA
140149
name: get_capital
150+
status: null
141151
type: function_call
142-
- call_id: call_Zmx4ZiPQOvoNEhLgG16TO3nx
152+
- call_id: call_YfwRsW8sUxDKipwyhWTzOXCA
143153
output: Potato City
144154
type: function_call_output
145-
instructions: ''
146155
model: gpt-4o
156+
stream: false
147157
tool_choice: auto
148158
tools:
149-
- description: ''
159+
- description: null
150160
name: get_capital
151161
parameters:
152162
additionalProperties: false
@@ -166,49 +176,60 @@ interactions:
166176
connection:
167177
- keep-alive
168178
content-length:
169-
- '1561'
179+
- '1810'
170180
content-type:
171181
- application/json
172182
openai-organization:
173183
- pydantic-28gund
174184
openai-processing-ms:
175-
- '470'
185+
- '1028'
186+
openai-project:
187+
- proj_dKobscVY9YJxeEaDJen54e3d
176188
openai-version:
177189
- '2020-10-01'
178190
strict-transport-security:
179191
- max-age=31536000; includeSubDomains; preload
180192
transfer-encoding:
181193
- chunked
182194
parsed_body:
183-
created_at: 1743075631
195+
background: false
196+
billing:
197+
payer: developer
198+
created_at: 1761323547
184199
error: null
185-
id: resp_67e5392f80808191affe6ff7af237dba0b8eafaa14d24d42
200+
id: resp_0e9950da9eac6a780068fbaa1bc030819da585a6f85ddad1e6
186201
incomplete_details: null
187-
instructions: ''
202+
instructions: null
188203
max_output_tokens: null
204+
max_tool_calls: null
189205
metadata: {}
190206
model: gpt-4o-2024-08-06
191207
object: response
192208
output:
193209
- content:
194210
- annotations: []
211+
logprobs: []
195212
text: The capital of PotatoLand is Potato City.
196213
type: output_text
197-
id: msg_67e5392fd7b4819190bec4e770968a9d0b8eafaa14d24d42
214+
id: msg_0e9950da9eac6a780068fbaa1c738c819d8bddf998e57232c3
198215
role: assistant
199216
status: completed
200217
type: message
201218
parallel_tool_calls: true
202219
previous_response_id: null
220+
prompt_cache_key: null
203221
reasoning:
204222
effort: null
205-
generate_summary: null
223+
summary: null
224+
safety_identifier: null
225+
service_tier: default
206226
status: completed
207227
store: true
208228
temperature: 1.0
209229
text:
210230
format:
211231
type: text
232+
verbosity: medium
212233
tool_choice: auto
213234
tools:
214235
- description: null
@@ -223,16 +244,17 @@ interactions:
223244
type: object
224245
strict: true
225246
type: function
247+
top_logprobs: 0
226248
top_p: 1.0
227249
truncation: disabled
228250
usage:
229-
input_tokens: 287
251+
input_tokens: 67
230252
input_tokens_details:
231253
cached_tokens: 0
232254
output_tokens: 11
233255
output_tokens_details:
234256
reasoning_tokens: 0
235-
total_tokens: 298
257+
total_tokens: 78
236258
user: null
237259
status:
238260
code: 200

0 commit comments

Comments
 (0)