|
54 | 54 | from .mock_openai import MockOpenAIResponses, get_mock_responses_kwargs, response_message |
55 | 55 |
|
56 | 56 | with try_import() as imports_successful: |
| 57 | + from openai.types.responses import ResponseFunctionWebSearch |
57 | 58 | from openai.types.responses.response_output_message import Content, ResponseOutputMessage, ResponseOutputText |
58 | 59 | from openai.types.responses.response_reasoning_item import ( |
59 | 60 | Content as ReasoningContent, |
@@ -1068,7 +1069,7 @@ async def test_openai_responses_model_web_search_tool_stream(allow_model_request |
1068 | 1069 | BuiltinToolReturnPart( |
1069 | 1070 | tool_name='web_search', |
1070 | 1071 | content={ |
1071 | | - 'sources': [{'type': 'api', 'url': None, 'name': 'oai-weather'}], |
| 1072 | + 'sources': [{'type': 'api', 'name': 'oai-weather'}], |
1072 | 1073 | 'status': 'completed', |
1073 | 1074 | }, |
1074 | 1075 | tool_call_id='ws_00a60507bf41223d0068c9d30021d081a0962d80d50c12e317', |
@@ -1155,7 +1156,7 @@ async def test_openai_responses_model_web_search_tool_stream(allow_model_request |
1155 | 1156 | index=2, |
1156 | 1157 | part=BuiltinToolReturnPart( |
1157 | 1158 | tool_name='web_search', |
1158 | | - content={'status': 'completed', 'sources': [{'type': 'api', 'url': None, 'name': 'oai-weather'}]}, |
| 1159 | + content={'status': 'completed', 'sources': [{'type': 'api', 'name': 'oai-weather'}]}, |
1159 | 1160 | tool_call_id='ws_00a60507bf41223d0068c9d30021d081a0962d80d50c12e317', |
1160 | 1161 | timestamp=IsDatetime(), |
1161 | 1162 | provider_name='openai', |
@@ -1249,7 +1250,7 @@ async def test_openai_responses_model_web_search_tool_stream(allow_model_request |
1249 | 1250 | BuiltinToolResultEvent( # pyright: ignore[reportDeprecated] |
1250 | 1251 | result=BuiltinToolReturnPart( |
1251 | 1252 | tool_name='web_search', |
1252 | | - content={'sources': [{'type': 'api', 'url': None, 'name': 'oai-weather'}], 'status': 'completed'}, |
| 1253 | + content={'sources': [{'type': 'api', 'name': 'oai-weather'}], 'status': 'completed'}, |
1253 | 1254 | tool_call_id='ws_00a60507bf41223d0068c9d30021d081a0962d80d50c12e317', |
1254 | 1255 | timestamp=IsDatetime(), |
1255 | 1256 | provider_name='openai', |
@@ -1288,7 +1289,7 @@ async def test_openai_responses_model_web_search_tool_stream(allow_model_request |
1288 | 1289 | BuiltinToolReturnPart( |
1289 | 1290 | tool_name='web_search', |
1290 | 1291 | content={ |
1291 | | - 'sources': [{'type': 'api', 'url': None, 'name': 'oai-weather'}], |
| 1292 | + 'sources': [{'type': 'api', 'name': 'oai-weather'}], |
1292 | 1293 | 'status': 'completed', |
1293 | 1294 | }, |
1294 | 1295 | tool_call_id='ws_00a60507bf41223d0068c9d31b6aec81a09d9e568afa7b59aa', |
@@ -8136,3 +8137,73 @@ async def test_openai_responses_runs_with_instructions_only( |
8136 | 8137 | assert result.output |
8137 | 8138 | assert isinstance(result.output, str) |
8138 | 8139 | assert len(result.output) > 0 |
| 8140 | + |
| 8141 | + |
| 8142 | +async def test_web_search_call_action_find_in_page(allow_model_requests: None): |
| 8143 | + """Test for https://github.com/pydantic/pydantic-ai/issues/3653""" |
| 8144 | + c1 = response_message( |
| 8145 | + [ |
| 8146 | + ResponseFunctionWebSearch.model_construct( |
| 8147 | + id='web-search-1', |
| 8148 | + action={ |
| 8149 | + 'type': 'find_in_page', |
| 8150 | + 'pattern': 'test', |
| 8151 | + 'url': 'https://example.com', |
| 8152 | + }, |
| 8153 | + status='completed', |
| 8154 | + type='web_search_call', |
| 8155 | + ), |
| 8156 | + ] |
| 8157 | + ) |
| 8158 | + c2 = response_message( |
| 8159 | + [ |
| 8160 | + ResponseOutputMessage( |
| 8161 | + id='output-1', |
| 8162 | + content=cast(list[Content], [ResponseOutputText(text='done', type='output_text', annotations=[])]), |
| 8163 | + role='assistant', |
| 8164 | + status='completed', |
| 8165 | + type='message', |
| 8166 | + ) |
| 8167 | + ] |
| 8168 | + ) |
| 8169 | + mock_client = MockOpenAIResponses.create_mock([c1, c2]) |
| 8170 | + model = OpenAIResponsesModel('gpt-5', provider=OpenAIProvider(openai_client=mock_client)) |
| 8171 | + agent = Agent(model=model) |
| 8172 | + |
| 8173 | + result = await agent.run('test') |
| 8174 | + |
| 8175 | + assert result.all_messages()[1] == snapshot( |
| 8176 | + ModelResponse( |
| 8177 | + parts=[ |
| 8178 | + BuiltinToolCallPart( |
| 8179 | + tool_name='web_search', |
| 8180 | + args={'type': 'find_in_page', 'pattern': 'test', 'url': 'https://example.com'}, |
| 8181 | + tool_call_id='web-search-1', |
| 8182 | + provider_name='openai', |
| 8183 | + ), |
| 8184 | + BuiltinToolReturnPart( |
| 8185 | + tool_name='web_search', |
| 8186 | + content={'status': 'completed'}, |
| 8187 | + tool_call_id='web-search-1', |
| 8188 | + timestamp=IsDatetime(), |
| 8189 | + provider_name='openai', |
| 8190 | + ), |
| 8191 | + ], |
| 8192 | + model_name='gpt-4o-123', |
| 8193 | + timestamp=IsDatetime(), |
| 8194 | + provider_name='openai', |
| 8195 | + provider_url='https://api.openai.com/v1', |
| 8196 | + provider_response_id='123', |
| 8197 | + run_id=IsStr(), |
| 8198 | + ) |
| 8199 | + ) |
| 8200 | + |
| 8201 | + response_kwargs = get_mock_responses_kwargs(mock_client) |
| 8202 | + assert response_kwargs[1]['input'][1] == snapshot( |
| 8203 | + { |
| 8204 | + 'id': 'web-search-1', |
| 8205 | + 'action': {'type': 'find_in_page', 'pattern': 'test', 'url': 'https://example.com'}, |
| 8206 | + 'status': 'completed', |
| 8207 | + 'type': 'web_search_call', |
| 8208 | + } |
| 8209 | + ) |
0 commit comments