18
18
using System . Collections . ObjectModel ;
19
19
using System . Linq ;
20
20
using Google . MiniJSON ;
21
+ using Firebase . VertexAI . Internal ;
21
22
22
23
namespace Firebase . VertexAI {
23
24
@@ -65,8 +66,8 @@ public IEnumerable<ModelContent.FunctionCallPart> FunctionCalls {
65
66
}
66
67
}
67
68
68
- // Hidden constructor, users don't need to make this, though they still technically can .
69
- internal GenerateContentResponse ( List < Candidate > candidates , PromptFeedback ? promptFeedback ,
69
+ // Hidden constructor, users don't need to make this.
70
+ private GenerateContentResponse ( List < Candidate > candidates , PromptFeedback ? promptFeedback ,
70
71
UsageMetadata ? usageMetadata ) {
71
72
_candidates = new ReadOnlyCollection < Candidate > ( candidates ?? new List < Candidate > ( ) ) ;
72
73
PromptFeedback = promptFeedback ;
@@ -78,48 +79,119 @@ internal static GenerateContentResponse FromJson(string jsonString) {
78
79
}
79
80
80
81
internal static GenerateContentResponse FromJson ( Dictionary < string , object > jsonDict ) {
81
- // Parse the Candidates
82
- List < Candidate > candidates = new ( ) ;
83
- if ( jsonDict . TryGetValue ( "candidates" , out object candidatesObject ) ) {
84
- if ( candidatesObject is not List < object > listOfCandidateObjects ) {
85
- throw new VertexAISerializationException ( "Invalid JSON format: 'candidates' is not a list." ) ;
86
- }
87
-
88
- candidates = listOfCandidateObjects
89
- . Select ( o => o as Dictionary < string , object > )
90
- . Where ( dict => dict != null )
91
- . Select ( Candidate . FromJson )
92
- . ToList ( ) ;
93
- }
94
-
95
- // TODO: Parse PromptFeedback and UsageMetadata
96
-
97
- return new GenerateContentResponse ( candidates , null , null ) ;
82
+ return new GenerateContentResponse (
83
+ jsonDict . ParseObjectList ( "candidates" , Candidate . FromJson ) ,
84
+ jsonDict . ParseNullableObject ( "promptFeedback" ,
85
+ Firebase . VertexAI . PromptFeedback . FromJson ) ,
86
+ jsonDict . ParseNullableObject ( "usageMetadata" ,
87
+ Firebase . VertexAI . UsageMetadata . FromJson ) ) ;
98
88
}
99
89
}
100
90
91
+ /// <summary>
92
+ /// A type describing possible reasons to block a prompt.
93
+ /// </summary>
101
94
public enum BlockReason {
102
- Unknown ,
95
+ /// <summary>
96
+ /// A new and not yet supported value.
97
+ /// </summary>
98
+ Unknown = 0 ,
99
+ /// <summary>
100
+ /// The prompt was blocked because it was deemed unsafe.
101
+ /// </summary>
103
102
Safety ,
103
+ /// <summary>
104
+ /// All other block reasons.
105
+ /// </summary>
104
106
Other ,
107
+ /// <summary>
108
+ /// The prompt was blocked because it contained terms from the terminology blocklist.
109
+ /// </summary>
105
110
Blocklist ,
111
+ /// <summary>
112
+ /// The prompt was blocked due to prohibited content.
113
+ /// </summary>
106
114
ProhibitedContent ,
107
115
}
108
116
117
+ /// <summary>
118
+ /// A metadata struct containing any feedback the model had on the prompt it was provided.
119
+ /// </summary>
109
120
public readonly struct PromptFeedback {
121
+ private readonly ReadOnlyCollection < SafetyRating > _safetyRatings ;
122
+
123
+ /// <summary>
124
+ /// The reason a prompt was blocked, if it was blocked.
125
+ /// </summary>
110
126
public BlockReason ? BlockReason { get ; }
127
+ /// <summary>
128
+ /// A human-readable description of the `BlockReason`.
129
+ /// </summary>
111
130
public string BlockReasonMessage { get ; }
112
- public IEnumerable < SafetyRating > SafetyRatings { get ; }
131
+ /// <summary>
132
+ /// The safety ratings of the prompt.
133
+ /// </summary>
134
+ public IEnumerable < SafetyRating > SafetyRatings =>
135
+ _safetyRatings ?? new ReadOnlyCollection < SafetyRating > ( new List < SafetyRating > ( ) ) ;
136
+
137
+ // Hidden constructor, users don't need to make this.
138
+ private PromptFeedback ( BlockReason ? blockReason , string blockReasonMessage ,
139
+ List < SafetyRating > safetyRatings ) {
140
+ BlockReason = blockReason ;
141
+ BlockReasonMessage = blockReasonMessage ;
142
+ _safetyRatings = new ReadOnlyCollection < SafetyRating > ( safetyRatings ?? new List < SafetyRating > ( ) ) ;
143
+ }
113
144
114
- // Hidden constructor, users don't need to make this
145
+ private static BlockReason ParseBlockReason ( string str ) {
146
+ return str switch {
147
+ "SAFETY" => Firebase . VertexAI . BlockReason . Safety ,
148
+ "OTHER" => Firebase . VertexAI . BlockReason . Other ,
149
+ "BLOCKLIST" => Firebase . VertexAI . BlockReason . Blocklist ,
150
+ "PROHIBITED_CONTENT" => Firebase . VertexAI . BlockReason . ProhibitedContent ,
151
+ _ => Firebase . VertexAI . BlockReason . Unknown ,
152
+ } ;
153
+ }
154
+
155
+ internal static PromptFeedback FromJson ( Dictionary < string , object > jsonDict ) {
156
+ return new PromptFeedback (
157
+ jsonDict . ParseNullableEnum ( "blockReason" , ParseBlockReason ) ,
158
+ jsonDict . ParseValue < string > ( "blockReasonMessage" ) ,
159
+ jsonDict . ParseObjectList ( "safetyRatings" , SafetyRating . FromJson ) ) ;
160
+ }
115
161
}
116
162
163
+ /// <summary>
164
+ /// Token usage metadata for processing the generate content request.
165
+ /// </summary>
117
166
public readonly struct UsageMetadata {
167
+ /// <summary>
168
+ /// The number of tokens in the request prompt.
169
+ /// </summary>
118
170
public int PromptTokenCount { get ; }
171
+ /// <summary>
172
+ /// The total number of tokens across the generated response candidates.
173
+ /// </summary>
119
174
public int CandidatesTokenCount { get ; }
175
+ /// <summary>
176
+ /// The total number of tokens in both the request and response.
177
+ /// </summary>
120
178
public int TotalTokenCount { get ; }
121
179
122
- // Hidden constructor, users don't need to make this
180
+ // TODO: New fields about ModalityTokenCount
181
+
182
+ // Hidden constructor, users don't need to make this.
183
+ private UsageMetadata ( int promptTC , int candidatesTC , int totalTC ) {
184
+ PromptTokenCount = promptTC ;
185
+ CandidatesTokenCount = candidatesTC ;
186
+ TotalTokenCount = totalTC ;
187
+ }
188
+
189
+ internal static UsageMetadata FromJson ( Dictionary < string , object > jsonDict ) {
190
+ return new UsageMetadata (
191
+ jsonDict . ParseValue < int > ( "promptTokenCount" ) ,
192
+ jsonDict . ParseValue < int > ( "candidatesTokenCount" ) ,
193
+ jsonDict . ParseValue < int > ( "totalTokenCount" ) ) ;
194
+ }
123
195
}
124
196
125
197
}
0 commit comments