From 7f3ec3f66820c45e78999ea7d068878fb934d900 Mon Sep 17 00:00:00 2001 From: Annie Luc Date: Wed, 11 Mar 2026 14:41:05 -0700 Subject: [PATCH] feat: Breaking change to Interactions API to refactor TextContent annotations to use specific citation types PiperOrigin-RevId: 882205237 --- google/genai/_interactions/types/__init__.py | 6 ++ .../genai/_interactions/types/annotation.py | 28 ++------ .../_interactions/types/annotation_param.py | 27 ++------ .../_interactions/types/content_delta.py | 16 +---- .../_interactions/types/file_citation.py | 44 +++++++++++++ .../types/file_citation_param.py | 43 ++++++++++++ .../types/file_search_result_content.py | 17 +---- .../types/file_search_result_content_param.py | 17 +---- .../types/google_search_result.py | 6 -- .../types/google_search_result_param.py | 6 -- .../_interactions/types/place_citation.py | 66 +++++++++++++++++++ .../types/place_citation_param.py | 66 +++++++++++++++++++ .../genai/_interactions/types/url_citation.py | 41 ++++++++++++ .../_interactions/types/url_citation_param.py | 40 +++++++++++ 14 files changed, 325 insertions(+), 98 deletions(-) create mode 100644 google/genai/_interactions/types/file_citation.py create mode 100644 google/genai/_interactions/types/file_citation_param.py create mode 100644 google/genai/_interactions/types/place_citation.py create mode 100644 google/genai/_interactions/types/place_citation_param.py create mode 100644 google/genai/_interactions/types/url_citation.py create mode 100644 google/genai/_interactions/types/url_citation_param.py diff --git a/google/genai/_interactions/types/__init__.py b/google/genai/_interactions/types/__init__.py index 726a498e5..f3331b0a4 100644 --- a/google/genai/_interactions/types/__init__.py +++ b/google/genai/_interactions/types/__init__.py @@ -33,15 +33,18 @@ from .content_stop import ContentStop as ContentStop from .image_config import ImageConfig as ImageConfig from .text_content import TextContent as TextContent +from .url_citation import URLCitation as URLCitation from .allowed_tools import AllowedTools as AllowedTools from .audio_content import AudioContent as AudioContent from .content_delta import ContentDelta as ContentDelta from .content_param import ContentParam as ContentParam from .content_start import ContentStart as ContentStart +from .file_citation import FileCitation as FileCitation from .image_content import ImageContent as ImageContent from .speech_config import SpeechConfig as SpeechConfig from .video_content import VideoContent as VideoContent from .function_param import FunctionParam as FunctionParam +from .place_citation import PlaceCitation as PlaceCitation from .thinking_level import ThinkingLevel as ThinkingLevel from .thought_content import ThoughtContent as ThoughtContent from .annotation_param import AnnotationParam as AnnotationParam @@ -52,14 +55,17 @@ from .image_config_param import ImageConfigParam as ImageConfigParam from .text_content_param import TextContentParam as TextContentParam from .tool_choice_config import ToolChoiceConfig as ToolChoiceConfig +from .url_citation_param import URLCitationParam as URLCitationParam from .url_context_result import URLContextResult as URLContextResult from .allowed_tools_param import AllowedToolsParam as AllowedToolsParam from .audio_content_param import AudioContentParam as AudioContentParam +from .file_citation_param import FileCitationParam as FileCitationParam from .image_content_param import ImageContentParam as ImageContentParam from .speech_config_param import SpeechConfigParam as SpeechConfigParam from .video_content_param import VideoContentParam as VideoContentParam from .dynamic_agent_config import DynamicAgentConfig as DynamicAgentConfig from .google_search_result import GoogleSearchResult as GoogleSearchResult +from .place_citation_param import PlaceCitationParam as PlaceCitationParam from .function_call_content import FunctionCallContent as FunctionCallContent from .interaction_sse_event import InteractionSSEEvent as InteractionSSEEvent from .thought_content_param import ThoughtContentParam as ThoughtContentParam diff --git a/google/genai/_interactions/types/annotation.py b/google/genai/_interactions/types/annotation.py index 3fc2f9234..9c38a05c8 100644 --- a/google/genai/_interactions/types/annotation.py +++ b/google/genai/_interactions/types/annotation.py @@ -15,28 +15,14 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Union +from typing_extensions import Annotated, TypeAlias -from .._models import BaseModel +from .._utils import PropertyInfo +from .url_citation import URLCitation +from .file_citation import FileCitation +from .place_citation import PlaceCitation __all__ = ["Annotation"] - -class Annotation(BaseModel): - """Citation information for model-generated content.""" - - end_index: Optional[int] = None - """End of the attributed segment, exclusive.""" - - source: Optional[str] = None - """Source attributed for a portion of the text. - - Could be a URL, title, or - other identifier. - """ - - start_index: Optional[int] = None - """Start of segment of the response that is attributed to this source. - - Index indicates the start of the segment, measured in bytes. - """ +Annotation: TypeAlias = Annotated[Union[URLCitation, FileCitation, PlaceCitation], PropertyInfo(discriminator="type")] diff --git a/google/genai/_interactions/types/annotation_param.py b/google/genai/_interactions/types/annotation_param.py index 649c1e510..ae6875035 100644 --- a/google/genai/_interactions/types/annotation_param.py +++ b/google/genai/_interactions/types/annotation_param.py @@ -17,26 +17,13 @@ from __future__ import annotations -from typing_extensions import TypedDict +from typing import Union +from typing_extensions import TypeAlias -__all__ = ["AnnotationParam"] - - -class AnnotationParam(TypedDict, total=False): - """Citation information for model-generated content.""" - - end_index: int - """End of the attributed segment, exclusive.""" +from .url_citation_param import URLCitationParam +from .file_citation_param import FileCitationParam +from .place_citation_param import PlaceCitationParam - source: str - """Source attributed for a portion of the text. - - Could be a URL, title, or - other identifier. - """ - - start_index: int - """Start of segment of the response that is attributed to this source. +__all__ = ["AnnotationParam"] - Index indicates the start of the segment, measured in bytes. - """ +AnnotationParam: TypeAlias = Union[URLCitationParam, FileCitationParam, PlaceCitationParam] diff --git a/google/genai/_interactions/types/content_delta.py b/google/genai/_interactions/types/content_delta.py index c2365dd22..451460138 100644 --- a/google/genai/_interactions/types/content_delta.py +++ b/google/genai/_interactions/types/content_delta.py @@ -60,7 +60,6 @@ "DeltaMCPServerToolResultResultItemsItem", "DeltaFileSearchCall", "DeltaFileSearchResult", - "DeltaFileSearchResultResult", "DeltaGoogleMapsCall", "DeltaGoogleMapsResult", ] @@ -307,26 +306,13 @@ class DeltaFileSearchCall(BaseModel): type: Literal["file_search_call"] -class DeltaFileSearchResultResult(BaseModel): - """The result of the File Search.""" - - file_search_store: Optional[str] = None - """The name of the file search store.""" - - text: Optional[str] = None - """The text of the search result.""" - - title: Optional[str] = None - """The title of the search result.""" - - class DeltaFileSearchResult(BaseModel): call_id: str """ID to match the ID from the function call block.""" type: Literal["file_search_result"] - result: Optional[List[DeltaFileSearchResultResult]] = None + result: Optional[List[object]] = None signature: Optional[str] = None """A signature hash for backend validation.""" diff --git a/google/genai/_interactions/types/file_citation.py b/google/genai/_interactions/types/file_citation.py new file mode 100644 index 000000000..6fa247093 --- /dev/null +++ b/google/genai/_interactions/types/file_citation.py @@ -0,0 +1,44 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["FileCitation"] + + +class FileCitation(BaseModel): + """A file citation annotation.""" + + type: Literal["file_citation"] + + document_uri: Optional[str] = None + """The URI of the file.""" + + end_index: Optional[int] = None + """End of the attributed segment, exclusive.""" + + file_name: Optional[str] = None + """The name of the file.""" + + source: Optional[str] = None + """Source attributed for a portion of the text.""" + + start_index: Optional[int] = None + """Start of segment of the response that is attributed to this source.""" diff --git a/google/genai/_interactions/types/file_citation_param.py b/google/genai/_interactions/types/file_citation_param.py new file mode 100644 index 000000000..5f4843d75 --- /dev/null +++ b/google/genai/_interactions/types/file_citation_param.py @@ -0,0 +1,43 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["FileCitationParam"] + + +class FileCitationParam(TypedDict, total=False): + """A file citation annotation.""" + + type: Required[Literal["file_citation"]] + + document_uri: str + """The URI of the file.""" + + end_index: int + """End of the attributed segment, exclusive.""" + + file_name: str + """The name of the file.""" + + source: str + """Source attributed for a portion of the text.""" + + start_index: int + """Start of segment of the response that is attributed to this source.""" diff --git a/google/genai/_interactions/types/file_search_result_content.py b/google/genai/_interactions/types/file_search_result_content.py index be786f037..31fa4d763 100644 --- a/google/genai/_interactions/types/file_search_result_content.py +++ b/google/genai/_interactions/types/file_search_result_content.py @@ -20,20 +20,7 @@ from .._models import BaseModel -__all__ = ["FileSearchResultContent", "Result"] - - -class Result(BaseModel): - """The result of the File Search.""" - - file_search_store: Optional[str] = None - """The name of the file search store.""" - - text: Optional[str] = None - """The text of the search result.""" - - title: Optional[str] = None - """The title of the search result.""" +__all__ = ["FileSearchResultContent"] class FileSearchResultContent(BaseModel): @@ -44,7 +31,7 @@ class FileSearchResultContent(BaseModel): type: Literal["file_search_result"] - result: Optional[List[Result]] = None + result: Optional[List[object]] = None """The results of the File Search.""" signature: Optional[str] = None diff --git a/google/genai/_interactions/types/file_search_result_content_param.py b/google/genai/_interactions/types/file_search_result_content_param.py index a891c0174..25b0dd4e6 100644 --- a/google/genai/_interactions/types/file_search_result_content_param.py +++ b/google/genai/_interactions/types/file_search_result_content_param.py @@ -20,20 +20,7 @@ from typing import Iterable from typing_extensions import Literal, Required, TypedDict -__all__ = ["FileSearchResultContentParam", "Result"] - - -class Result(TypedDict, total=False): - """The result of the File Search.""" - - file_search_store: str - """The name of the file search store.""" - - text: str - """The text of the search result.""" - - title: str - """The title of the search result.""" +__all__ = ["FileSearchResultContentParam"] class FileSearchResultContentParam(TypedDict, total=False): @@ -44,7 +31,7 @@ class FileSearchResultContentParam(TypedDict, total=False): type: Required[Literal["file_search_result"]] - result: Iterable[Result] + result: Iterable[object] """The results of the File Search.""" signature: str diff --git a/google/genai/_interactions/types/google_search_result.py b/google/genai/_interactions/types/google_search_result.py index b3e835767..9691f5d40 100644 --- a/google/genai/_interactions/types/google_search_result.py +++ b/google/genai/_interactions/types/google_search_result.py @@ -27,9 +27,3 @@ class GoogleSearchResult(BaseModel): search_suggestions: Optional[str] = None """Web content snippet that can be embedded in a web page or an app webview.""" - - title: Optional[str] = None - """Title of the search result.""" - - url: Optional[str] = None - """URI reference of the search result.""" diff --git a/google/genai/_interactions/types/google_search_result_param.py b/google/genai/_interactions/types/google_search_result_param.py index f2cb06360..be1d11d51 100644 --- a/google/genai/_interactions/types/google_search_result_param.py +++ b/google/genai/_interactions/types/google_search_result_param.py @@ -27,9 +27,3 @@ class GoogleSearchResultParam(TypedDict, total=False): search_suggestions: str """Web content snippet that can be embedded in a web page or an app webview.""" - - title: str - """Title of the search result.""" - - url: str - """URI reference of the search result.""" diff --git a/google/genai/_interactions/types/place_citation.py b/google/genai/_interactions/types/place_citation.py new file mode 100644 index 000000000..21e52636b --- /dev/null +++ b/google/genai/_interactions/types/place_citation.py @@ -0,0 +1,66 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["PlaceCitation", "ReviewSnippet"] + + +class ReviewSnippet(BaseModel): + """ + Encapsulates a snippet of a user review that answers a question about + the features of a specific place in Google Maps. + """ + + review_id: Optional[str] = None + """The ID of the review snippet.""" + + title: Optional[str] = None + """Title of the review.""" + + url: Optional[str] = None + """A link that corresponds to the user review on Google Maps.""" + + +class PlaceCitation(BaseModel): + """A place citation annotation.""" + + type: Literal["place_citation"] + + end_index: Optional[int] = None + """End of the attributed segment, exclusive.""" + + name: Optional[str] = None + """Title of the place.""" + + place_id: Optional[str] = None + """The ID of the place, in `places/{place_id}` format.""" + + review_snippets: Optional[List[ReviewSnippet]] = None + """ + Snippets of reviews that are used to generate answers about the + features of a given place in Google Maps. + """ + + start_index: Optional[int] = None + """Start of segment of the response that is attributed to this source.""" + + url: Optional[str] = None + """URI reference of the place.""" diff --git a/google/genai/_interactions/types/place_citation_param.py b/google/genai/_interactions/types/place_citation_param.py new file mode 100644 index 000000000..498b4d9a8 --- /dev/null +++ b/google/genai/_interactions/types/place_citation_param.py @@ -0,0 +1,66 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["PlaceCitationParam", "ReviewSnippet"] + + +class ReviewSnippet(TypedDict, total=False): + """ + Encapsulates a snippet of a user review that answers a question about + the features of a specific place in Google Maps. + """ + + review_id: str + """The ID of the review snippet.""" + + title: str + """Title of the review.""" + + url: str + """A link that corresponds to the user review on Google Maps.""" + + +class PlaceCitationParam(TypedDict, total=False): + """A place citation annotation.""" + + type: Required[Literal["place_citation"]] + + end_index: int + """End of the attributed segment, exclusive.""" + + name: str + """Title of the place.""" + + place_id: str + """The ID of the place, in `places/{place_id}` format.""" + + review_snippets: Iterable[ReviewSnippet] + """ + Snippets of reviews that are used to generate answers about the + features of a given place in Google Maps. + """ + + start_index: int + """Start of segment of the response that is attributed to this source.""" + + url: str + """URI reference of the place.""" diff --git a/google/genai/_interactions/types/url_citation.py b/google/genai/_interactions/types/url_citation.py new file mode 100644 index 000000000..e1c27bffb --- /dev/null +++ b/google/genai/_interactions/types/url_citation.py @@ -0,0 +1,41 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from .._models import BaseModel + +__all__ = ["URLCitation"] + + +class URLCitation(BaseModel): + """A URL citation annotation.""" + + type: Literal["url_citation"] + + end_index: Optional[int] = None + """End of the attributed segment, exclusive.""" + + start_index: Optional[int] = None + """Start of segment of the response that is attributed to this source.""" + + title: Optional[str] = None + """The title of the URL.""" + + url: Optional[str] = None + """The URL.""" diff --git a/google/genai/_interactions/types/url_citation_param.py b/google/genai/_interactions/types/url_citation_param.py new file mode 100644 index 000000000..6df7dbcae --- /dev/null +++ b/google/genai/_interactions/types/url_citation_param.py @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["URLCitationParam"] + + +class URLCitationParam(TypedDict, total=False): + """A URL citation annotation.""" + + type: Required[Literal["url_citation"]] + + end_index: int + """End of the attributed segment, exclusive.""" + + start_index: int + """Start of segment of the response that is attributed to this source.""" + + title: str + """The title of the URL.""" + + url: str + """The URL."""