@@ -19,7 +19,8 @@ import 'schema.dart';
19
19
/// Response for Count Tokens
20
20
final class CountTokensResponse {
21
21
/// Constructor
22
- CountTokensResponse (this .totalTokens, {this .totalBillableCharacters});
22
+ CountTokensResponse (this .totalTokens,
23
+ {this .totalBillableCharacters, this .promptTokensDetails});
23
24
24
25
/// The number of tokens that the `model` tokenizes the `prompt` into.
25
26
///
@@ -30,6 +31,9 @@ final class CountTokensResponse {
30
31
///
31
32
/// Always non-negative.
32
33
final int ? totalBillableCharacters;
34
+
35
+ /// List of modalities that were processed in the request input.
36
+ final List <ModalityTokenCount >? promptTokensDetails;
33
37
}
34
38
35
39
/// Response from the model; supports multiple candidates.
@@ -128,11 +132,12 @@ final class PromptFeedback {
128
132
/// Metadata on the generation request's token usage.
129
133
final class UsageMetadata {
130
134
/// Constructor
131
- UsageMetadata ._({
132
- this .promptTokenCount,
133
- this .candidatesTokenCount,
134
- this .totalTokenCount,
135
- });
135
+ UsageMetadata ._(
136
+ {this .promptTokenCount,
137
+ this .candidatesTokenCount,
138
+ this .totalTokenCount,
139
+ this .promptTokensDetails,
140
+ this .candidatesTokensDetails});
136
141
137
142
/// Number of tokens in the prompt.
138
143
final int ? promptTokenCount;
@@ -142,6 +147,12 @@ final class UsageMetadata {
142
147
143
148
/// Total token count for the generation request (prompt + candidates).
144
149
final int ? totalTokenCount;
150
+
151
+ /// List of modalities that were processed in the request input.
152
+ final List <ModalityTokenCount >? promptTokensDetails;
153
+
154
+ /// List of modalities that were returned in the response.
155
+ final List <ModalityTokenCount >? candidatesTokensDetails;
145
156
}
146
157
147
158
/// Response candidate generated from a [GenerativeModel] .
@@ -481,6 +492,62 @@ enum FinishReason {
481
492
String toString () => name;
482
493
}
483
494
495
+ /// Represents token counting info for a single modality.
496
+ final class ModalityTokenCount {
497
+ /// Constructor
498
+ ModalityTokenCount (this .modality, this .tokenCount);
499
+
500
+ /// The modality associated with this token count.
501
+ final ContentModality modality;
502
+
503
+ /// The number of tokens counted.
504
+ final int tokenCount;
505
+ }
506
+
507
+ /// Content part modality.
508
+ enum ContentModality {
509
+ /// Unspecified modality.
510
+ unspecified ('MODALITY_UNSPECIFIED' ),
511
+
512
+ /// Plain text.
513
+ text ('TEXT' ),
514
+
515
+ /// Image.
516
+ image ('IMAGE' ),
517
+
518
+ /// Video.
519
+ video ('VIDEO' ),
520
+
521
+ /// Audio.
522
+ audio ('AUDIO' ),
523
+
524
+ /// Document, e.g. PDF.
525
+ document ('DOCUMENT' );
526
+
527
+ const ContentModality (this ._jsonString);
528
+
529
+ static ContentModality _parseValue (Object jsonObject) {
530
+ return switch (jsonObject) {
531
+ 'MODALITY_UNSPECIFIED' => ContentModality .unspecified,
532
+ 'TEXT' => ContentModality .text,
533
+ 'IMAGE' => ContentModality .image,
534
+ 'video' => ContentModality .video,
535
+ 'audio' => ContentModality .audio,
536
+ 'document' => ContentModality .document,
537
+ _ =>
538
+ throw FormatException ('Unhandled ContentModality format' , jsonObject),
539
+ };
540
+ }
541
+
542
+ final String _jsonString;
543
+
544
+ @override
545
+ String toString () => name;
546
+
547
+ /// Convert to json format.
548
+ Object toJson () => _jsonString;
549
+ }
550
+
484
551
/// Safety setting, affecting the safety-blocking behavior.
485
552
///
486
553
/// Passing a safety setting for a category changes the allowed probability that
@@ -696,16 +763,28 @@ GenerateContentResponse parseGenerateContentResponse(Object jsonObject) {
696
763
/// Parse the json to [CountTokensResponse]
697
764
CountTokensResponse parseCountTokensResponse (Object jsonObject) {
698
765
if (jsonObject case {'error' : final Object error}) throw parseError (error);
699
- if (jsonObject case {'totalTokens' : final int totalTokens}) {
700
- if (jsonObject
701
- case {'totalBillableCharacters' : final int totalBillableCharacters}) {
702
- return CountTokensResponse (totalTokens,
703
- totalBillableCharacters: totalBillableCharacters);
704
- } else {
705
- return CountTokensResponse (totalTokens);
706
- }
766
+
767
+ if (jsonObject is ! Map ) {
768
+ throw unhandledFormat ('CountTokensResponse' , jsonObject);
707
769
}
708
- throw unhandledFormat ('CountTokensResponse' , jsonObject);
770
+
771
+ final totalTokens = jsonObject['totalTokens' ] as int ;
772
+ final totalBillableCharacters = switch (jsonObject) {
773
+ {'totalBillableCharacters' : final int totalBillableCharacters} =>
774
+ totalBillableCharacters,
775
+ _ => null ,
776
+ };
777
+ final promptTokensDetails = switch (jsonObject) {
778
+ {'promptTokensDetails' : final List <Object ?> promptTokensDetails} =>
779
+ promptTokensDetails.map (_parseModalityTokenCount).toList (),
780
+ _ => null ,
781
+ };
782
+
783
+ return CountTokensResponse (
784
+ totalTokens,
785
+ totalBillableCharacters: totalBillableCharacters,
786
+ promptTokensDetails: promptTokensDetails,
787
+ );
709
788
}
710
789
711
790
Candidate _parseCandidate (Object ? jsonObject) {
@@ -777,10 +856,30 @@ UsageMetadata _parseUsageMetadata(Object jsonObject) {
777
856
{'totalTokenCount' : final int totalTokenCount} => totalTokenCount,
778
857
_ => null ,
779
858
};
859
+ final promptTokensDetails = switch (jsonObject) {
860
+ {'promptTokensDetails' : final List <Object ?> promptTokensDetails} =>
861
+ promptTokensDetails.map (_parseModalityTokenCount).toList (),
862
+ _ => null ,
863
+ };
864
+ final candidatesTokensDetails = switch (jsonObject) {
865
+ {'candidatesTokensDetails' : final List <Object ?> candidatesTokensDetails} =>
866
+ candidatesTokensDetails.map (_parseModalityTokenCount).toList (),
867
+ _ => null ,
868
+ };
780
869
return UsageMetadata ._(
781
870
promptTokenCount: promptTokenCount,
782
871
candidatesTokenCount: candidatesTokenCount,
783
- totalTokenCount: totalTokenCount);
872
+ totalTokenCount: totalTokenCount,
873
+ promptTokensDetails: promptTokensDetails,
874
+ candidatesTokensDetails: candidatesTokensDetails);
875
+ }
876
+
877
+ ModalityTokenCount _parseModalityTokenCount (Object ? jsonObject) {
878
+ if (jsonObject is ! Map ) {
879
+ throw unhandledFormat ('ModalityTokenCount' , jsonObject);
880
+ }
881
+ return ModalityTokenCount (ContentModality ._parseValue (jsonObject['modality' ]),
882
+ jsonObject['tokenCount' ] as int );
784
883
}
785
884
786
885
SafetyRating _parseSafetyRating (Object ? jsonObject) {
0 commit comments