@@ -24,14 +24,20 @@ import '../api.dart'
24
24
FinishReason,
25
25
GenerateContentResponse,
26
26
GenerationConfig,
27
+ GroundingChunk,
28
+ GroundingMetadata,
29
+ GroundingSupport,
27
30
HarmBlockThreshold,
28
31
HarmCategory,
29
32
HarmProbability,
30
33
PromptFeedback,
31
34
SafetyRating,
32
35
SafetySetting,
36
+ SearchEntryPoint,
37
+ Segment,
33
38
SerializationStrategy,
34
39
UsageMetadata,
40
+ WebGroundingChunk,
35
41
createUsageMetadata;
36
42
import '../content.dart'
37
43
show Content, FunctionCall, InlineDataPart, Part, TextPart;
@@ -206,6 +212,11 @@ Candidate _parseCandidate(Object? jsonObject) {
206
212
{'finishMessage' : final String finishMessage} => finishMessage,
207
213
_ => null
208
214
},
215
+ groundingMetadata: switch (jsonObject) {
216
+ {'groundingMetadata' : final Object groundingMetadata} =>
217
+ _parseGroundingMetadata (groundingMetadata),
218
+ _ => null
219
+ },
209
220
);
210
221
}
211
222
@@ -299,6 +310,117 @@ Citation _parseCitationSource(Object? jsonObject) {
299
310
);
300
311
}
301
312
313
+ GroundingMetadata _parseGroundingMetadata (Object ? jsonObject) {
314
+ if (jsonObject is ! Map ) {
315
+ throw unhandledFormat ('GroundingMetadata' , jsonObject);
316
+ }
317
+
318
+ final searchEntryPoint = switch (jsonObject) {
319
+ {'searchEntryPoint' : final Object ? searchEntryPoint} =>
320
+ _parseSearchEntryPoint (searchEntryPoint),
321
+ _ => null ,
322
+ };
323
+ final groundingChunks = switch (jsonObject) {
324
+ {'groundingChunks' : final List <Object ?> groundingChunks} =>
325
+ groundingChunks.map (_parseGroundingChunk).toList (),
326
+ _ => null ,
327
+ } ??
328
+ [];
329
+ // Filters out null elements, which are returned from _parseGroundingSupport when
330
+ // segment is null.
331
+ final groundingSupport = switch (jsonObject) {
332
+ {'groundingSupport' : final List <Object ?> groundingSupport} =>
333
+ groundingSupport
334
+ .map (_parseGroundingSupport)
335
+ .whereType <GroundingSupport >()
336
+ .toList (),
337
+ _ => null ,
338
+ } ??
339
+ [];
340
+ final webSearchQueries = switch (jsonObject) {
341
+ {'webSearchQueries' : final List <String >? webSearchQueries} =>
342
+ webSearchQueries,
343
+ _ => null ,
344
+ } ??
345
+ [];
346
+
347
+ return GroundingMetadata (
348
+ searchEntryPoint: searchEntryPoint,
349
+ groundingChunks: groundingChunks,
350
+ groundingSupport: groundingSupport,
351
+ webSearchQueries: webSearchQueries);
352
+ }
353
+
354
+ Segment _parseSegment (Object ? jsonObject) {
355
+ if (jsonObject is ! Map ) {
356
+ throw unhandledFormat ('Segment' , jsonObject);
357
+ }
358
+
359
+ return Segment (
360
+ partIndex: (jsonObject['partIndex' ] as int ? ) ?? 0 ,
361
+ startIndex: (jsonObject['startIndex' ] as int ? ) ?? 0 ,
362
+ endIndex: (jsonObject['endIndex' ] as int ? ) ?? 0 ,
363
+ text: (jsonObject['text' ] as String ? ) ?? '' );
364
+ }
365
+
366
+ WebGroundingChunk _parseWebGroundingChunk (Object ? jsonObject) {
367
+ if (jsonObject is ! Map ) {
368
+ throw unhandledFormat ('WebGroundingChunk' , jsonObject);
369
+ }
370
+
371
+ return WebGroundingChunk (
372
+ uri: jsonObject['uri' ] as String ? ,
373
+ title: jsonObject['title' ] as String ? ,
374
+ domain: jsonObject['domain' ] as String ? ,
375
+ );
376
+ }
377
+
378
+ GroundingChunk _parseGroundingChunk (Object ? jsonObject) {
379
+ if (jsonObject is ! Map ) {
380
+ throw unhandledFormat ('GroundingChunk' , jsonObject);
381
+ }
382
+
383
+ return GroundingChunk (
384
+ web: jsonObject['web' ] != null
385
+ ? _parseWebGroundingChunk (jsonObject['web' ])
386
+ : null ,
387
+ );
388
+ }
389
+
390
+ GroundingSupport ? _parseGroundingSupport (Object ? jsonObject) {
391
+ if (jsonObject is ! Map ) {
392
+ throw unhandledFormat ('GroundingSupport' , jsonObject);
393
+ }
394
+
395
+ final segment = switch (jsonObject) {
396
+ {'segment' : final Object ? segment} => _parseSegment (segment),
397
+ _ => null ,
398
+ };
399
+ if (segment == null ) {
400
+ return null ;
401
+ }
402
+
403
+ return GroundingSupport (
404
+ segment: segment,
405
+ groundingChunkIndices:
406
+ (jsonObject['groundingChunkIndices' ] as List <int >? ) ?? []);
407
+ }
408
+
409
+ SearchEntryPoint _parseSearchEntryPoint (Object ? jsonObject) {
410
+ if (jsonObject is ! Map ) {
411
+ throw unhandledFormat ('SearchEntryPoint' , jsonObject);
412
+ }
413
+
414
+ final renderedContent = jsonObject['renderedContent' ] as String ? ;
415
+ if (renderedContent == null ) {
416
+ throw unhandledFormat ('SearchEntryPoint' , jsonObject);
417
+ }
418
+
419
+ return SearchEntryPoint (
420
+ renderedContent: renderedContent,
421
+ );
422
+ }
423
+
302
424
Content _parseGoogleAIContent (Object jsonObject) {
303
425
return switch (jsonObject) {
304
426
{'parts' : final List <Object ?> parts} => Content (
0 commit comments