diff --git a/pydantic_ai_slim/pydantic_ai/messages.py b/pydantic_ai_slim/pydantic_ai/messages.py index 3f3ea0c13d..8463f2858a 100644 --- a/pydantic_ai_slim/pydantic_ai/messages.py +++ b/pydantic_ai_slim/pydantic_ai/messages.py @@ -754,6 +754,10 @@ class TextPart: part_kind: Literal['text'] = 'text' """Part type identifier, this is available on all parts as a discriminator.""" + # TODO(Marcelo): Is this better as a list or a set? + citations: list[Citation] = field(default_factory=list) + """The citations of the response.""" + def has_content(self) -> bool: """Return `True` if the text content is non-empty.""" return bool(self.content) @@ -761,6 +765,27 @@ def has_content(self) -> bool: __repr__ = _utils.dataclasses_no_defaults_repr +@dataclass(repr=False) +class URLCitation: + """A citation from a text response.""" + + url: str + """The URL of the citation.""" + + title: str + """The title of the citation.""" + + # TODO(Marcelo): Should we add a `vendor_details` field or something? + + kind: Literal['url-citation'] = 'url-citation' + """The type of the citation.""" + + __repr__ = _utils.dataclasses_no_defaults_repr + + +Citation = Annotated[URLCitation, pydantic.Discriminator('kind')] + + @dataclass(repr=False) class ThinkingPart: """A thinking response from a model.""" diff --git a/pydantic_ai_slim/pydantic_ai/models/anthropic.py b/pydantic_ai_slim/pydantic_ai/models/anthropic.py index 0459af9376..9033013681 100644 --- a/pydantic_ai_slim/pydantic_ai/models/anthropic.py +++ b/pydantic_ai_slim/pydantic_ai/models/anthropic.py @@ -8,6 +8,7 @@ from datetime import datetime, timezone from typing import Any, Literal, Union, cast, overload +from anthropic.types.beta import BetaCitationsWebSearchResultLocation from typing_extensions import assert_never from pydantic_ai.builtin_tools import CodeExecutionTool, WebSearchTool @@ -33,6 +34,7 @@ ThinkingPart, ToolCallPart, ToolReturnPart, + URLCitation, UserPromptPart, ) from ..profiles import ModelProfileSpec @@ -289,7 +291,15 @@ def _process_response(self, response: BetaMessage) -> ModelResponse: items: list[ModelResponsePart] = [] for item in response.content: if isinstance(item, BetaTextBlock): - items.append(TextPart(content=item.text)) + if item.citations: + citations = [ + URLCitation(url=citation.url, title=citation.title or citation.cited_text) + for citation in item.citations + if isinstance(citation, BetaCitationsWebSearchResultLocation) + ] + else: + citations = [] + items.append(TextPart(content=item.text, citations=citations)) elif isinstance(item, (BetaWebSearchToolResultBlock, BetaCodeExecutionToolResultBlock)): items.append( BuiltinToolReturnPart( diff --git a/pydantic_ai_slim/pydantic_ai/models/openai.py b/pydantic_ai_slim/pydantic_ai/models/openai.py index a980b27fa0..30d888d160 100644 --- a/pydantic_ai_slim/pydantic_ai/models/openai.py +++ b/pydantic_ai_slim/pydantic_ai/models/openai.py @@ -36,6 +36,7 @@ ThinkingPart, ToolCallPart, ToolReturnPart, + URLCitation, UserPromptPart, VideoUrl, ) @@ -72,6 +73,7 @@ ) from openai.types.responses import ComputerToolParam, FileSearchToolParam, WebSearchToolParam from openai.types.responses.response_input_param import FunctionCallOutput, Message + from openai.types.responses.response_output_text import AnnotationURLCitation from openai.types.shared import ReasoningEffort from openai.types.shared_params import Reasoning except ImportError as _import_error: @@ -480,6 +482,7 @@ def _process_response(self, response: chat.ChatCompletion | str) -> ModelRespons } if choice.message.content is not None: + # NOTE: Should we include the citations on each `TextPart` here? items.extend(split_content_into_text_and_thinking(choice.message.content, self.profile.thinking_tags)) if choice.message.tool_calls is not None: for c in choice.message.tool_calls: @@ -796,7 +799,16 @@ def _process_response(self, response: responses.Response) -> ModelResponse: elif item.type == 'message': for content in item.content: if content.type == 'output_text': # pragma: no branch - items.append(TextPart(content.text)) + items.append( + TextPart( + content.text, + citations=[ + URLCitation(url=annotation.url, title=annotation.title) + for annotation in content.annotations + if isinstance(annotation, AnnotationURLCitation) + ], + ) + ) elif item.type == 'function_call': items.append(ToolCallPart(item.name, item.arguments, tool_call_id=item.call_id)) return ModelResponse( diff --git a/tests/models/cassettes/test_model_names/test_known_model_names.yaml b/tests/models/cassettes/test_model_names/test_known_model_names.yaml index afcb3a49b0..f594f6b27b 100644 --- a/tests/models/cassettes/test_model_names/test_known_model_names.yaml +++ b/tests/models/cassettes/test_model_names/test_known_model_names.yaml @@ -12,6 +12,8 @@ interactions: uri: https://us.inference.heroku.com/available-models response: headers: + connection: + - keep-alive content-length: - '760' content-security-policy: diff --git a/tests/models/cassettes/test_openai/test_openai_web_search_tool.yaml b/tests/models/cassettes/test_openai/test_openai_web_search_tool.yaml index cd48b3ea92..d187e8f64d 100644 --- a/tests/models/cassettes/test_openai/test_openai_web_search_tool.yaml +++ b/tests/models/cassettes/test_openai/test_openai_web_search_tool.yaml @@ -8,7 +8,7 @@ interactions: connection: - keep-alive content-length: - - '218' + - '236' content-type: - application/json host: @@ -18,7 +18,7 @@ interactions: messages: - content: You are a helpful assistant. role: system - - content: What day is today? + - content: What are the latest news in Iceland? role: user model: gpt-4o-search-preview stream: false @@ -34,13 +34,15 @@ interactions: connection: - keep-alive content-length: - - '785' + - '6079' content-type: - application/json openai-organization: - pydantic-28gund openai-processing-ms: - - '2051' + - '11243' + openai-project: + - proj_dKobscVY9YJxeEaDJen54e3d openai-version: - '2020-10-01' strict-transport-security: @@ -52,27 +54,87 @@ interactions: - finish_reason: stop index: 0 message: - annotations: [] - content: 'May 14, 2025, 8:51:29 AM ' + annotations: + - type: url_citation + url_citation: + end_index: 700 + start_index: 565 + title: Iceland volcano emits smoke and glowing lava in 12th eruption since 2021 + url: https://www.reuters.com/business/environment/iceland-volcano-erupts-12th-time-since-2021-2025-07-16/?utm_source=openai + - type: url_citation + url_citation: + end_index: 1247 + start_index: 1106 + title: Iceland to launch negotiations on security, defence partnership with EU + url: https://www.reuters.com/world/iceland-launch-negotiations-security-defence-partnership-with-eu-2025-07-17/?utm_source=openai + - type: url_citation + url_citation: + end_index: 1674 + start_index: 1605 + title: News | Icelandic Meteorological office + url: https://en.vedur.is/about-imo/news?utm_source=openai + - type: url_citation + url_citation: + end_index: 2011 + start_index: 1924 + title: Latest news - Iceland Monitor + url: https://icelandmonitor.mbl.is/news/latest/?utm_source=openai + - type: url_citation + url_citation: + end_index: 2250 + start_index: 2051 + title: Iceland to launch negotiations on security, defence partnership with EU + url: https://www.reuters.com/world/iceland-launch-negotiations-security-defence-partnership-with-eu-2025-07-17/?utm_source=openai + - type: url_citation + url_citation: + end_index: 2410 + start_index: 2253 + title: Iceland volcano eruption forces evacuation of town and iconic geothermal spa + url: https://apnews.com/article/c72f44eb9ecb5f2d87e87fd53ed3b26d?utm_source=openai + - type: url_citation + url_citation: + end_index: 2607 + start_index: 2413 + title: Iceland volcano emits smoke and glowing lava in 12th eruption since 2021 + url: https://www.reuters.com/business/environment/iceland-volcano-erupts-12th-time-since-2021-2025-07-16/?utm_source=openai + content: "Here are some of the latest news updates from Iceland:\n\n**Volcanic Activity**\n\nOn July 16, 2025, a + volcanic eruption occurred on the Reykjanes Peninsula in southwest Iceland. The eruption produced smoke and vibrant + lava flows from a fissure spanning 700 to 1,000 meters. Authorities evacuated the Blue Lagoon geothermal spa and + the nearby town of Grindavik as a precaution. The Icelandic Meteorological Office described the eruption as relatively + small, posing no immediate threat to infrastructure, and flights at Reykjavik's Keflavik airport remained unaffected. + ([reuters.com](https://www.reuters.com/business/environment/iceland-volcano-erupts-12th-time-since-2021-2025-07-16/?utm_source=openai))\n\n**Political + Developments**\n\nIceland is set to begin negotiations on a security and defense partnership with the European + Union. Prime Minister Kristrún Frostadóttir announced the talks, aiming to establish cooperation in areas such + as infrastructure, civil protection, dual-use defense investment, and addressing hybrid and cyber threats. The + discussions are expected to conclude by the end of the year. ([reuters.com](https://www.reuters.com/world/iceland-launch-negotiations-security-defence-partnership-with-eu-2025-07-17/?utm_source=openai))\n\n**Environmental + Concerns**\n\nThe Icelandic Meteorological Office has issued warnings about air pollution resulting from the recent + volcanic eruption. Volcanic haze has spread widely, with gas pollution, mainly sulfur dioxide, reaching populated + areas such as Reykjanesbær. Vulnerable groups are advised to limit time outdoors if they experience discomfort. + ([en.vedur.is](https://en.vedur.is/about-imo/news?utm_source=openai))\n\n**Cultural Events**\n\nThe town of Hafnarfjörður + recently celebrated the ninth annual \"Í hjarta Hafnarfjarðar\" (\"In the Heart of Hafnarfjörður\") festival. + The event featured various festivities and was noted for its positive impact on the community. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest/?utm_source=openai))\n\n\n## + Recent Developments in Iceland:\n- [Iceland to launch negotiations on security, defence partnership with EU](https://www.reuters.com/world/iceland-launch-negotiations-security-defence-partnership-with-eu-2025-07-17/?utm_source=openai)\n- + [Iceland volcano eruption forces evacuation of town and iconic geothermal spa](https://apnews.com/article/c72f44eb9ecb5f2d87e87fd53ed3b26d?utm_source=openai)\n- + [Iceland volcano emits smoke and glowing lava in 12th eruption since 2021](https://www.reuters.com/business/environment/iceland-volcano-erupts-12th-time-since-2021-2025-07-16/?utm_source=openai) " refusal: null role: assistant - created: 1747227087 - id: chatcmpl-e05fbf7b-44c0-406d-8662-bc7a9a518747 + created: 1756109356 + id: chatcmpl-b2ed94c7-51cb-4fb3-bf4d-4138b0c2a0fc model: gpt-4o-search-preview-2025-03-11 object: chat.completion system_fingerprint: '' usage: - completion_tokens: 17 + completion_tokens: 603 completion_tokens_details: accepted_prediction_tokens: 0 audio_tokens: 0 reasoning_tokens: 0 rejected_prediction_tokens: 0 - prompt_tokens: 11 + prompt_tokens: 14 prompt_tokens_details: audio_tokens: 0 cached_tokens: 0 - total_tokens: 28 + total_tokens: 617 status: code: 200 message: OK diff --git a/tests/models/cassettes/test_openai_responses/test_openai_responses_model_web_search_tool.yaml b/tests/models/cassettes/test_openai_responses/test_openai_responses_model_web_search_tool.yaml index 5996ed6c48..7e772af09b 100644 --- a/tests/models/cassettes/test_openai_responses/test_openai_responses_model_web_search_tool.yaml +++ b/tests/models/cassettes/test_openai_responses/test_openai_responses_model_web_search_tool.yaml @@ -8,7 +8,7 @@ interactions: connection: - keep-alive content-length: - - '231' + - '246' content-type: - application/json host: @@ -16,7 +16,7 @@ interactions: method: POST parsed_body: input: - - content: What day is it today? + - content: What are the latest news in Iceland? role: user instructions: You are a helpful assistant. model: gpt-4o @@ -33,13 +33,15 @@ interactions: connection: - keep-alive content-length: - - '2569' + - '5795' content-type: - application/json openai-organization: - pydantic-28gund openai-processing-ms: - - '3632' + - '8810' + openai-project: + - proj_dKobscVY9YJxeEaDJen54e3d openai-version: - '2020-10-01' strict-transport-security: @@ -47,39 +49,83 @@ interactions: transfer-encoding: - chunked parsed_body: - created_at: 1747227360 + background: false + created_at: 1756110386 error: null - id: resp_682492e0aab88191afcadcbbb85e1a490e7f27fcb18d04ed + id: resp_68ac1e32b0108192973c8cfec29c2e61014ed998995dd5ee incomplete_details: null instructions: You are a helpful assistant. max_output_tokens: null + max_tool_calls: null metadata: {} model: gpt-4o-2024-08-06 object: response output: - - id: ws_682492e1b7a08191b30170317ea7ee570e7f27fcb18d04ed + - action: + query: latest news in Iceland October 2023 + type: search + id: ws_68ac1e339ee8819289d2eb5604ce44ce014ed998995dd5ee status: completed type: web_search_call - content: - - annotations: [] - text: "Today is Wednesday, May 14, 2025.\n\n## Weather for San Francisco, CA:\nCurrent Conditions: Mostly clear, - 50°F (10°C)\n\nDaily Forecast:\n* Wednesday, May 14: Low: 51°F (10°C), High: 65°F (18°C), Description: Areas of - low clouds early; otherwise, mostly sunny\n* Thursday, May 15: Low: 53°F (12°C), High: 66°F (19°C), Description: - Areas of low clouds, then sun\n* Friday, May 16: Low: 53°F (12°C), High: 64°F (18°C), Description: Partly sunny\n* - Saturday, May 17: Low: 52°F (11°C), High: 63°F (17°C), Description: Low clouds breaking for some sun; breezy in - the afternoon\n* Sunday, May 18: Low: 51°F (10°C), High: 68°F (20°C), Description: Clouds yielding to sun\n* Monday, - May 19: Low: 53°F (12°C), High: 68°F (20°C), Description: Sunny\n* Tuesday, May 20: Low: 52°F (11°C), High: 70°F - (21°C), Description: Mostly sunny\n " + - annotations: + - end_index: 651 + start_index: 538 + title: 2023–2025 Sundhnúkur eruptions + type: url_citation + url: https://en.wikipedia.org/wiki/2023%E2%80%932025_Sundhn%C3%BAkur_eruptions?utm_source=openai + - end_index: 1010 + start_index: 904 + title: 2024 Icelandic presidential election + type: url_citation + url: https://en.wikipedia.org/wiki/2024_Icelandic_presidential_election?utm_source=openai + - end_index: 1489 + start_index: 1382 + title: 2024 Icelandic parliamentary election + type: url_citation + url: https://en.wikipedia.org/wiki/2024_Icelandic_parliamentary_election?utm_source=openai + - end_index: 1849 + start_index: 1761 + title: Latest news - Iceland Monitor + type: url_citation + url: https://icelandmonitor.mbl.is/news/latest//?utm_source=openai + - end_index: 2142 + start_index: 2054 + title: Latest news - Iceland Monitor + type: url_citation + url: https://icelandmonitor.mbl.is/news/latest//?utm_source=openai + logprobs: [] + text: "As of August 25, 2025, here are the latest developments in Iceland:\n\n**Volcanic Activity:**\n\nThe Reykjanes + Peninsula has experienced a series of volcanic eruptions since December 2023, collectively known as the 2023–2025 + Sundhnúkur eruptions. The most recent eruption began on July 16, 2025, and lasted approximately 20 days. While + this eruption did not threaten infrastructure, it caused significant gas pollution that spread unusually far, + resulting in higher pollution levels in nearby towns and cities compared to previous eruptions. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2023%E2%80%932025_Sundhn%C3%BAkur_eruptions?utm_source=openai))\n\n**Political + Developments:**\n\n- **Presidential Election:** On June 1, 2024, entrepreneur Halla Tómasdóttir was elected President + of Iceland, succeeding Guðni Th. Jóhannesson, who did not seek a third term. Tómasdóttir assumed office on August + 1, 2024. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2024_Icelandic_presidential_election?utm_source=openai))\n\n- + **Parliamentary Election:** Following the collapse of the coalition government in October 2024, parliamentary + elections were held on November 30, 2024. The Social Democratic Alliance, led by Kristrún Frostadóttir, won a + plurality of seats, marking a significant shift in Iceland's political landscape. Frostadóttir was sworn in as + Prime Minister on December 21, 2024. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2024_Icelandic_parliamentary_election?utm_source=openai))\n\n**Environmental + and Cultural Events:**\n\n- **Geological Recognition:** In September 2024, the Reykjanes Peninsula and Vatnajökull + glacier were included in the International Geological Union's list of 100 geological heritage sites, highlighting + their global significance. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest//?utm_source=openai))\n\n- + **Peace Column Renovation:** Renovation work on the Peace Column in Viðey was completed in September 2024, ensuring + its readiness for illumination on October 9, coinciding with John Lennon's birthday. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest//?utm_source=openai))\n\nPlease + note that the situation, especially regarding volcanic activity, is subject to change. For the most current information, + consult local news sources and official government communications. " type: output_text - id: msg_682492e36ab08191813ec707a61c272f0e7f27fcb18d04ed + id: msg_68ac1e3616548192bc0265a336983d12014ed998995dd5ee role: assistant status: completed type: message parallel_tool_calls: true previous_response_id: null + prompt_cache_key: null reasoning: effort: null summary: null + safety_identifier: null service_tier: default status: completed store: true @@ -87,6 +133,7 @@ interactions: text: format: type: text + verbosity: medium tool_choice: auto tools: - search_context_size: medium @@ -97,16 +144,17 @@ interactions: region: null timezone: null type: approximate + top_logprobs: 0 top_p: 1.0 truncation: disabled usage: - input_tokens: 317 + input_tokens: 319 input_tokens_details: cached_tokens: 0 - output_tokens: 286 + output_tokens: 556 output_tokens_details: reasoning_tokens: 0 - total_tokens: 603 + total_tokens: 875 user: null status: code: 200 diff --git a/tests/models/test_anthropic.py b/tests/models/test_anthropic.py index 38f8adb1b4..b04991d5da 100644 --- a/tests/models/test_anthropic.py +++ b/tests/models/test_anthropic.py @@ -37,6 +37,7 @@ ThinkingPartDelta, ToolCallPart, ToolReturnPart, + URLCitation, UserPromptPart, ) from pydantic_ai.output import NativeOutput, PromptedOutput, TextOutput, ToolOutput @@ -1338,7 +1339,7 @@ async def test_anthropic_web_search_tool(allow_model_requests: None, anthropic_a ModelRequest(parts=[UserPromptPart(content='What day is today?', timestamp=IsDatetime())]), ModelResponse( parts=[ - TextPart(content="Let me search for current events to help establish today's date."), + TextPart(content="Let me search for current events to help establish today's date.", citations=[]), BuiltinToolCallPart( tool_name='web_search', args={'query': 'current events today August 14 2025'}, @@ -1419,37 +1420,67 @@ async def test_anthropic_web_search_tool(allow_model_requests: None, anthropic_a content="""\ Based on the search results, today is Thursday, August 14, 2025. This is confirmed by multiple sources: -""" +""", + citations=[], + ), + TextPart( + content='Today is August 14, 2025 (Thursday)', + citations=[ + URLCitation( + url='https://en.wikipedia.org/wiki/Portal:Current_events/2025_August_14', + title='Portal:Current events/2025 August 14 - Wikipedia', + ) + ], ), - TextPart(content='Today is August 14, 2025 (Thursday)'), TextPart( content="""\ Several major events are happening today, including: -""" +""", + citations=[], ), TextPart( - content='There is an ongoing situation in Gaza with Israeli forces launching a massive aerial bombardment of Gaza City' + content='There is an ongoing situation in Gaza with Israeli forces launching a massive aerial bombardment of Gaza City', + citations=[ + URLCitation( + url='https://en.wikipedia.org/wiki/Portal:Current_events', + title='Portal:Current events - Wikipedia', + ) + ], ), TextPart( content="""\ -""" +""", + citations=[], ), TextPart( - content='U.S. President Donald Trump has announced he will be meeting Russian President Vladimir Putin in Alaska tomorrow (August 15) to discuss ending the war in Ukraine' + content='U.S. President Donald Trump has announced he will be meeting Russian President Vladimir Putin in Alaska tomorrow (August 15) to discuss ending the war in Ukraine', + citations=[ + URLCitation( + url='https://en.wikipedia.org/wiki/Portal:Current_events/August_2025', + title='Portal:Current events/August 2025 - Wikipedia', + ) + ], ), TextPart( content="""\ -""" +""", + citations=[], ), TextPart( - content="Mount Lewotobi Laki Laki in Indonesia is experiencing its second consecutive day of eruption, sending volcanic materials and ash up to 18 km into the sky. This is one of Indonesia's largest eruptions since 2010, though fortunately no casualties have been reported." + content="Mount Lewotobi Laki Laki in Indonesia is experiencing its second consecutive day of eruption, sending volcanic materials and ash up to 18 km into the sky. This is one of Indonesia's largest eruptions since 2010, though fortunately no casualties have been reported.", + citations=[ + URLCitation( + url='https://en.wikipedia.org/wiki/Portal:Current_events/August_2025', + title='Portal:Current events/August 2025 - Wikipedia', + ) + ], ), ], usage=RequestUsage( diff --git a/tests/models/test_openai.py b/tests/models/test_openai.py index 4f7012f689..9b25d77bd5 100644 --- a/tests/models/test_openai.py +++ b/tests/models/test_openai.py @@ -2189,8 +2189,32 @@ async def test_openai_web_search_tool(allow_model_requests: None, openai_api_key m, instructions='You are a helpful assistant.', builtin_tools=[WebSearchTool(search_context_size='low')] ) - result = await agent.run('What day is today?') - assert result.output == snapshot('May 14, 2025, 8:51:29 AM ') + result = await agent.run('What are the latest news in Iceland?') + assert result.output == snapshot("""\ +Here are some of the latest news updates from Iceland: + +**Volcanic Activity** + +On July 16, 2025, a volcanic eruption occurred on the Reykjanes Peninsula in southwest Iceland. The eruption produced smoke and vibrant lava flows from a fissure spanning 700 to 1,000 meters. Authorities evacuated the Blue Lagoon geothermal spa and the nearby town of Grindavik as a precaution. The Icelandic Meteorological Office described the eruption as relatively small, posing no immediate threat to infrastructure, and flights at Reykjavik's Keflavik airport remained unaffected. ([reuters.com](https://www.reuters.com/business/environment/iceland-volcano-erupts-12th-time-since-2021-2025-07-16/?utm_source=openai)) + +**Political Developments** + +Iceland is set to begin negotiations on a security and defense partnership with the European Union. Prime Minister Kristrún Frostadóttir announced the talks, aiming to establish cooperation in areas such as infrastructure, civil protection, dual-use defense investment, and addressing hybrid and cyber threats. The discussions are expected to conclude by the end of the year. ([reuters.com](https://www.reuters.com/world/iceland-launch-negotiations-security-defence-partnership-with-eu-2025-07-17/?utm_source=openai)) + +**Environmental Concerns** + +The Icelandic Meteorological Office has issued warnings about air pollution resulting from the recent volcanic eruption. Volcanic haze has spread widely, with gas pollution, mainly sulfur dioxide, reaching populated areas such as Reykjanesbær. Vulnerable groups are advised to limit time outdoors if they experience discomfort. ([en.vedur.is](https://en.vedur.is/about-imo/news?utm_source=openai)) + +**Cultural Events** + +The town of Hafnarfjörður recently celebrated the ninth annual "Í hjarta Hafnarfjarðar" ("In the Heart of Hafnarfjörður") festival. The event featured various festivities and was noted for its positive impact on the community. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest/?utm_source=openai)) + + +## Recent Developments in Iceland: +- [Iceland to launch negotiations on security, defence partnership with EU](https://www.reuters.com/world/iceland-launch-negotiations-security-defence-partnership-with-eu-2025-07-17/?utm_source=openai) +- [Iceland volcano eruption forces evacuation of town and iconic geothermal spa](https://apnews.com/article/c72f44eb9ecb5f2d87e87fd53ed3b26d?utm_source=openai) +- [Iceland volcano emits smoke and glowing lava in 12th eruption since 2021](https://www.reuters.com/business/environment/iceland-volcano-erupts-12th-time-since-2021-2025-07-16/?utm_source=openai) \ +""") async def test_openai_web_search_tool_with_user_location(allow_model_requests: None, openai_api_key: str): diff --git a/tests/models/test_openai_responses.py b/tests/models/test_openai_responses.py index c4e3f44414..27b91e2feb 100644 --- a/tests/models/test_openai_responses.py +++ b/tests/models/test_openai_responses.py @@ -24,6 +24,7 @@ TextPartDelta, ToolCallPart, ToolReturnPart, + URLCitation, UserPromptPart, ) from pydantic_ai.output import NativeOutput, PromptedOutput, TextOutput, ToolOutput @@ -417,7 +418,17 @@ async def test_openai_responses_model_builtin_tools(allow_model_requests: None, ## OpenAI's GPT-5 Launch Faces Mixed Reactions: - [OpenAI's big GPT-5 launch gets bumpy](https://www.axios.com/2025/08/12/gpt-5-bumpy-launch-openai?utm_source=openai) \ -""" +""", + citations=[ + URLCitation( + url='https://www.axios.com/2025/08/12/gpt-5-bumpy-launch-openai?utm_source=openai', + title="OpenAI's big GPT-5 launch gets bumpy", + ), + URLCitation( + url='https://www.axios.com/2025/08/12/gpt-5-bumpy-launch-openai?utm_source=openai', + title="OpenAI's big GPT-5 launch gets bumpy", + ), + ], ) ], usage=RequestUsage(input_tokens=320, output_tokens=159, details={'reasoning_tokens': 0}), @@ -458,23 +469,90 @@ async def test_openai_responses_model_web_search_tool(allow_model_requests: None m = OpenAIResponsesModel('gpt-4o', provider=OpenAIProvider(api_key=openai_api_key)) agent = Agent(m, instructions='You are a helpful assistant.', builtin_tools=[WebSearchTool()]) - result = await agent.run('What day is it today?') + result = await agent.run('What are the latest news in Iceland?') assert result.output == snapshot("""\ -Today is Wednesday, May 14, 2025. +As of August 25, 2025, here are the latest developments in Iceland: -## Weather for San Francisco, CA: -Current Conditions: Mostly clear, 50°F (10°C) +**Volcanic Activity:** -Daily Forecast: -* Wednesday, May 14: Low: 51°F (10°C), High: 65°F (18°C), Description: Areas of low clouds early; otherwise, mostly sunny -* Thursday, May 15: Low: 53°F (12°C), High: 66°F (19°C), Description: Areas of low clouds, then sun -* Friday, May 16: Low: 53°F (12°C), High: 64°F (18°C), Description: Partly sunny -* Saturday, May 17: Low: 52°F (11°C), High: 63°F (17°C), Description: Low clouds breaking for some sun; breezy in the afternoon -* Sunday, May 18: Low: 51°F (10°C), High: 68°F (20°C), Description: Clouds yielding to sun -* Monday, May 19: Low: 53°F (12°C), High: 68°F (20°C), Description: Sunny -* Tuesday, May 20: Low: 52°F (11°C), High: 70°F (21°C), Description: Mostly sunny - \ +The Reykjanes Peninsula has experienced a series of volcanic eruptions since December 2023, collectively known as the 2023–2025 Sundhnúkur eruptions. The most recent eruption began on July 16, 2025, and lasted approximately 20 days. While this eruption did not threaten infrastructure, it caused significant gas pollution that spread unusually far, resulting in higher pollution levels in nearby towns and cities compared to previous eruptions. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2023%E2%80%932025_Sundhn%C3%BAkur_eruptions?utm_source=openai)) + +**Political Developments:** + +- **Presidential Election:** On June 1, 2024, entrepreneur Halla Tómasdóttir was elected President of Iceland, succeeding Guðni Th. Jóhannesson, who did not seek a third term. Tómasdóttir assumed office on August 1, 2024. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2024_Icelandic_presidential_election?utm_source=openai)) + +- **Parliamentary Election:** Following the collapse of the coalition government in October 2024, parliamentary elections were held on November 30, 2024. The Social Democratic Alliance, led by Kristrún Frostadóttir, won a plurality of seats, marking a significant shift in Iceland's political landscape. Frostadóttir was sworn in as Prime Minister on December 21, 2024. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2024_Icelandic_parliamentary_election?utm_source=openai)) + +**Environmental and Cultural Events:** + +- **Geological Recognition:** In September 2024, the Reykjanes Peninsula and Vatnajökull glacier were included in the International Geological Union's list of 100 geological heritage sites, highlighting their global significance. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest//?utm_source=openai)) + +- **Peace Column Renovation:** Renovation work on the Peace Column in Viðey was completed in September 2024, ensuring its readiness for illumination on October 9, coinciding with John Lennon's birthday. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest//?utm_source=openai)) + +Please note that the situation, especially regarding volcanic activity, is subject to change. For the most current information, consult local news sources and official government communications. \ """) + assert result.all_messages() == snapshot( + [ + ModelRequest( + parts=[UserPromptPart(content='What are the latest news in Iceland?', timestamp=IsDatetime())], + instructions='You are a helpful assistant.', + ), + ModelResponse( + parts=[ + TextPart( + content="""\ +As of August 25, 2025, here are the latest developments in Iceland: + +**Volcanic Activity:** + +The Reykjanes Peninsula has experienced a series of volcanic eruptions since December 2023, collectively known as the 2023–2025 Sundhnúkur eruptions. The most recent eruption began on July 16, 2025, and lasted approximately 20 days. While this eruption did not threaten infrastructure, it caused significant gas pollution that spread unusually far, resulting in higher pollution levels in nearby towns and cities compared to previous eruptions. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2023%E2%80%932025_Sundhn%C3%BAkur_eruptions?utm_source=openai)) + +**Political Developments:** + +- **Presidential Election:** On June 1, 2024, entrepreneur Halla Tómasdóttir was elected President of Iceland, succeeding Guðni Th. Jóhannesson, who did not seek a third term. Tómasdóttir assumed office on August 1, 2024. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2024_Icelandic_presidential_election?utm_source=openai)) + +- **Parliamentary Election:** Following the collapse of the coalition government in October 2024, parliamentary elections were held on November 30, 2024. The Social Democratic Alliance, led by Kristrún Frostadóttir, won a plurality of seats, marking a significant shift in Iceland's political landscape. Frostadóttir was sworn in as Prime Minister on December 21, 2024. ([en.wikipedia.org](https://en.wikipedia.org/wiki/2024_Icelandic_parliamentary_election?utm_source=openai)) + +**Environmental and Cultural Events:** + +- **Geological Recognition:** In September 2024, the Reykjanes Peninsula and Vatnajökull glacier were included in the International Geological Union's list of 100 geological heritage sites, highlighting their global significance. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest//?utm_source=openai)) + +- **Peace Column Renovation:** Renovation work on the Peace Column in Viðey was completed in September 2024, ensuring its readiness for illumination on October 9, coinciding with John Lennon's birthday. ([icelandmonitor.mbl.is](https://icelandmonitor.mbl.is/news/latest//?utm_source=openai)) + +Please note that the situation, especially regarding volcanic activity, is subject to change. For the most current information, consult local news sources and official government communications. \ +""", + citations=[ + URLCitation( + url='https://en.wikipedia.org/wiki/2023%E2%80%932025_Sundhn%C3%BAkur_eruptions?utm_source=openai', + title='2023–2025 Sundhnúkur eruptions', + ), + URLCitation( + url='https://en.wikipedia.org/wiki/2024_Icelandic_presidential_election?utm_source=openai', + title='2024 Icelandic presidential election', + ), + URLCitation( + url='https://en.wikipedia.org/wiki/2024_Icelandic_parliamentary_election?utm_source=openai', + title='2024 Icelandic parliamentary election', + ), + URLCitation( + url='https://icelandmonitor.mbl.is/news/latest//?utm_source=openai', + title='Latest news - Iceland Monitor', + ), + URLCitation( + url='https://icelandmonitor.mbl.is/news/latest//?utm_source=openai', + title='Latest news - Iceland Monitor', + ), + ], + ) + ], + usage=RequestUsage(input_tokens=319, output_tokens=556, details={'reasoning_tokens': 0}), + model_name='gpt-4o-2024-08-06', + timestamp=IsDatetime(), + provider_name='openai', + provider_request_id='resp_68ac1e32b0108192973c8cfec29c2e61014ed998995dd5ee', + ), + ] + ) async def test_openai_responses_model_web_search_tool_with_user_location( diff --git a/tests/test_agent.py b/tests/test_agent.py index 991c9891b4..2f3b054574 100644 --- a/tests/test_agent.py +++ b/tests/test_agent.py @@ -3050,7 +3050,7 @@ def test_binary_content_serializable(): 'kind': 'request', }, { - 'parts': [{'content': 'success (no tool calls)', 'part_kind': 'text'}], + 'parts': [{'content': 'success (no tool calls)', 'part_kind': 'text', 'citations': None}], 'usage': { 'input_tokens': 56, 'cache_write_tokens': 0, @@ -3105,7 +3105,7 @@ def test_image_url_serializable(): 'kind': 'request', }, { - 'parts': [{'content': 'success (no tool calls)', 'part_kind': 'text'}], + 'parts': [{'content': 'success (no tool calls)', 'part_kind': 'text', 'citations': None}], 'usage': { 'input_tokens': 51, 'cache_write_tokens': 0,