Repository navigation
Conversation
A source part meant a citation for some providers and a page a provider- executed search found for others, with nothing to tell them apart. SourceContent.ToolCallID (StreamPart.SourceToolCallID when streaming) names the tool call that returned the source and stays empty for citations. The agent copies it from stream parts, and the custom JSON marshalers keep it so a found page does not read back as a citation.
Sources from a web_search_tool_result are pages the search found, not citations, so they carry the search's tool_use_id in Generate and Stream.
The Responses API only returns the pages a web search found when the request includes web_search_call.action.sources, so requests with a web search tool now add it once. When a web_search_call item closes, its found pages are emitted as sources tagged with the item ID, before the tool result. The tool call input is built from the action: the queries of a search (or the deprecated query), the URL of open_page, or the URL and pattern of find_in_page. WebSearchCallMetadata keeps the item status and those action fields. Streaming reads found pages from the item, not response.completed, because the final summary also lists pages the answer cited. Generate only has the final output, so cited pages can appear as found pages there. The TestOpenAIWebSearch cassettes were re-recorded because the request body now carries the include.
Keep each explanation in one place and match the surrounding comment style. Restore upstream comments that still hold.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
sourcepart is a citation for OpenAI (url_citation) and a found page for Anthropic (web_search_tool_result), with nothing to tell the two apart. OpenAI Responses also never requests the pages a search found, and drops the search queries, the item status, and the URL and pattern ofopen_pageandfind_in_page.Change
SourceContent.ToolCallID(StreamPart.SourceToolCallIDwhen streaming) is set on sources a provider-executed tool call returned. Citations leave it empty.web_search_call.action.sourcesinclude when a web search tool is set;{"type":"search","queries":[…]};Status,Queries,URLandPatterninWebSearchCallMetadata.OpenAI consumers now receive found pages as sources, as Anthropic consumers already do.
Found pages come from the streamed
output_item.done, notresponse.completed: in live gpt-4.1-mini and gpt-5-mini streams, the final summary also listed the pages the answer cited among each search's sources.Generateonly has that final output, so there it can report cited pages as found pages.Replay is unchanged.
Tests
Unit tests cover each action shape in
GenerateandStream, cited pages staying untagged, a failed search, include deduplication, Anthropic tagging, and theSourceContentJSON round trip. TheTestOpenAIWebSearchcassettes are re-recorded because the request now carries the include.