@@ -136,13 +136,16 @@ public struct Candidate: Sendable {
136136 /// Cited works in the model's response content, if it exists.
137137 public let citationMetadata : CitationMetadata ?
138138
139+ public let groundingMetadata : GroundingMetadata ?
140+
139141 /// Initializer for SwiftUI previews or tests.
140142 public init ( content: ModelContent , safetyRatings: [ SafetyRating ] , finishReason: FinishReason ? ,
141- citationMetadata: CitationMetadata ? ) {
143+ citationMetadata: CitationMetadata ? , groundingMetadata : GroundingMetadata ? = nil ) {
142144 self . content = content
143145 self . safetyRatings = safetyRatings
144146 self . finishReason = finishReason
145147 self . citationMetadata = citationMetadata
148+ self . groundingMetadata = groundingMetadata
146149 }
147150}
148151
@@ -299,6 +302,110 @@ public struct PromptFeedback: Sendable {
299302 }
300303}
301304
305+ /// Metadata returned to the client when grounding is enabled.
306+ ///
307+ /// > Important: If using Grounding with Google Search, you are required to comply with the
308+ /// "Grounding with Google Search" usage requirements for your chosen API provider:
309+ /// [Gemini Developer API](https://ai.google.dev/gemini-api/terms#grounding-with-google-search)
310+ /// or Vertex AI Gemini API (see [Service Terms](https://cloud.google.com/terms/service-terms)
311+ /// section within the Service Specific Terms).
312+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
313+ public struct GroundingMetadata : Sendable {
314+ /// A list of web search queries that the model performed to gather the grounding information.
315+ /// These can be used to allow users to explore the search results themselves.
316+ public let webSearchQueries : [ String ]
317+ /// A list of ``GroundingChunk`` structs. Each chunk represents a piece of retrieved content
318+ /// (e.g., from a web page) that the model used to ground its response.
319+ public let groundingChunks : [ GroundingChunk ]
320+ /// A list of ``GroundingSupport`` structs. Each object details how specific segments of the
321+ /// model's response are supported by the `groundingChunks`.
322+ public let groundingSupports : [ GroundingSupport ]
323+ /// Google Search entry point for web searches.
324+ /// This contains an HTML/CSS snippet that **must** be embedded in an app to display a Google
325+ /// Search entry point for follow-up web searches related to the model's "Grounded Response".
326+ public let searchEntryPoint : SearchEntryPoint ?
327+
328+ /// A struct representing the Google Search entry point.
329+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
330+ public struct SearchEntryPoint : Sendable {
331+ /// An HTML/CSS snippet that can be embedded in your app.
332+ ///
333+ /// To ensure proper rendering, it's recommended to display this content within a `WKWebView`.
334+ public let renderedContent : String
335+ }
336+
337+ /// Represents a chunk of retrieved data that supports a claim in the model's response. This is
338+ /// part of the grounding information provided when grounding is enabled.
339+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
340+ public struct GroundingChunk : Sendable {
341+ /// Contains details if the grounding chunk is from a web source.
342+ public let web : WebGroundingChunk ?
343+ }
344+
345+ /// A grounding chunk sourced from the web.
346+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
347+ public struct WebGroundingChunk : Sendable {
348+ /// The URI of the retrieved web page.
349+ public let uri : String ?
350+ /// The title of the retrieved web page.
351+ public let title : String ?
352+ /// The domain of the original URI from which the content was retrieved.
353+ ///
354+ /// This field is only populated when using the Vertex AI Gemini API.
355+ public let domain : String ?
356+ }
357+
358+ /// Provides information about how a specific segment of the model's response is supported by the
359+ /// retrieved grounding chunks.
360+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
361+ public struct GroundingSupport : Sendable {
362+ /// Specifies the segment of the model's response content that this grounding support pertains
363+ /// to.
364+ public let segment : Segment
365+
366+ /// A list of indices that refer to specific ``GroundingChunk`` structs within the
367+ /// ``GroundingMetadata/groundingChunks`` array. These referenced chunks are the sources that
368+ /// support the claim made in the associated `segment` of the response. For example, an array
369+ /// `[1, 3, 4]`
370+ /// means that `groundingChunks[1]`, `groundingChunks[3]`, `groundingChunks[4]` are the
371+ /// retrieved content supporting this part of the response.
372+ public let groundingChunkIndices : [ Int ]
373+
374+ struct Internal {
375+ let segment : Segment ?
376+ let groundingChunkIndices : [ Int ]
377+
378+ func toPublic( ) -> GroundingSupport ? {
379+ if segment == nil {
380+ return nil
381+ }
382+ return GroundingSupport (
383+ segment: segment!,
384+ groundingChunkIndices: groundingChunkIndices
385+ )
386+ }
387+ }
388+ }
389+ }
390+
391+ /// Represents a specific segment within a ``ModelContent`` struct, often used to pinpoint the
392+ /// exact location of text or data that grounding information refers to.
393+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
394+ public struct Segment : Sendable {
395+ /// The zero-based index of the ``Part`` object within the `parts` array of its parent
396+ /// ``ModelContent`` object. This identifies which part of the content the segment belongs to.
397+ public let partIndex : Int
398+ /// The zero-based start index of the segment within the specified ``Part``, measured in UTF-8
399+ /// bytes. This offset is inclusive, starting from 0 at the beginning of the part's content.
400+ public let startIndex : Int
401+ /// The zero-based end index of the segment within the specified ``Part``, measured in UTF-8
402+ /// bytes. This offset is exclusive, meaning the character at this index is not included in the
403+ /// segment.
404+ public let endIndex : Int
405+ /// The text corresponding to the segment from the response.
406+ public let text : String
407+ }
408+
302409// MARK: - Codable Conformances
303410
304411@available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
@@ -369,6 +476,7 @@ extension Candidate: Decodable {
369476 case safetyRatings
370477 case finishReason
371478 case citationMetadata
479+ case groundingMetadata
372480 }
373481
374482 /// Initializes a response from a decoder. Used for decoding server responses; not for public
@@ -414,6 +522,11 @@ extension Candidate: Decodable {
414522 CitationMetadata . self,
415523 forKey: . citationMetadata
416524 )
525+
526+ groundingMetadata = try container. decodeIfPresent (
527+ GroundingMetadata . self,
528+ forKey: . groundingMetadata
529+ )
417530 }
418531}
419532
@@ -513,3 +626,74 @@ extension PromptFeedback: Decodable {
513626 }
514627 }
515628}
629+
630+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
631+ extension GroundingMetadata : Decodable {
632+ enum CodingKeys : String , CodingKey {
633+ case webSearchQueries
634+ case groundingChunks
635+ case groundingSupports
636+ case searchEntryPoint
637+ }
638+
639+ public init ( from decoder: Decoder ) throws {
640+ let container = try decoder. container ( keyedBy: CodingKeys . self)
641+ webSearchQueries = try container. decodeIfPresent ( [ String ] . self, forKey: . webSearchQueries) ?? [ ]
642+ groundingChunks = try container. decodeIfPresent (
643+ [ GroundingChunk ] . self,
644+ forKey: . groundingChunks
645+ ) ?? [ ]
646+ groundingSupports = try container. decodeIfPresent (
647+ [ GroundingSupport . Internal ] . self,
648+ forKey: . groundingSupports
649+ ) ? . compactMap { $0. toPublic ( ) } ?? [ ]
650+ searchEntryPoint = try container. decodeIfPresent (
651+ SearchEntryPoint . self,
652+ forKey: . searchEntryPoint
653+ )
654+ }
655+ }
656+
657+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
658+ extension GroundingMetadata . SearchEntryPoint : Decodable { }
659+
660+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
661+ extension GroundingMetadata . GroundingChunk : Decodable { }
662+
663+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
664+ extension GroundingMetadata . WebGroundingChunk : Decodable { }
665+
666+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
667+ extension GroundingMetadata . GroundingSupport . Internal : Decodable {
668+ enum CodingKeys : String , CodingKey {
669+ case segment
670+ case groundingChunkIndices
671+ }
672+
673+ public init ( from decoder: Decoder ) throws {
674+ let container = try decoder. container ( keyedBy: CodingKeys . self)
675+ segment = try container. decodeIfPresent ( Segment . self, forKey: . segment)
676+ groundingChunkIndices = try container. decodeIfPresent (
677+ [ Int ] . self,
678+ forKey: . groundingChunkIndices
679+ ) ?? [ ]
680+ }
681+ }
682+
683+ @available ( iOS 15 . 0 , macOS 12 . 0 , macCatalyst 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
684+ extension Segment : Decodable {
685+ enum CodingKeys : String , CodingKey {
686+ case partIndex
687+ case startIndex
688+ case endIndex
689+ case text
690+ }
691+
692+ public init ( from decoder: Decoder ) throws {
693+ let container = try decoder. container ( keyedBy: CodingKeys . self)
694+ partIndex = try container. decodeIfPresent ( Int . self, forKey: . partIndex) ?? 0
695+ startIndex = try container. decodeIfPresent ( Int . self, forKey: . startIndex) ?? 0
696+ endIndex = try container. decodeIfPresent ( Int . self, forKey: . endIndex) ?? 0
697+ text = try container. decodeIfPresent ( String . self, forKey: . text) ?? " "
698+ }
699+ }
0 commit comments