@@ -27,15 +27,16 @@ public class GenerativeModel
27
27
private const string MediaType = "application/json" ;
28
28
29
29
private readonly bool _useVertexAi ;
30
- private readonly bool _useHeaderApiKey ;
31
- private readonly bool _useHeaderProjectId ;
32
30
private readonly string _model ;
33
- private readonly string ? _apiKey ;
34
- private readonly string ? _projectId ;
35
- private readonly string ? _region ;
31
+ private readonly string _region = "us-central1" ;
36
32
private readonly string _publisher = "google" ;
37
33
private readonly JsonSerializerOptions _options ;
34
+
35
+ private bool _useHeaderApiKey ;
36
+ private string ? _apiKey ;
38
37
private string ? _accessToken ;
38
+ private bool _useHeaderProjectId ;
39
+ private string ? _projectId ;
39
40
private List < SafetySetting > ? _safetySettings ;
40
41
private GenerationConfig ? _generationConfig ;
41
42
private List < Tool > ? _tools ;
@@ -117,48 +118,74 @@ private string Method
117
118
/// <returns>Name of the model.</returns>
118
119
public string Name => _model ;
119
120
121
+ public string ? ApiKey
122
+ {
123
+ set
124
+ {
125
+ _apiKey = value ;
126
+ if ( ! string . IsNullOrEmpty ( _apiKey ) )
127
+ {
128
+ _useHeaderApiKey = Client . DefaultRequestHeaders . Contains ( "x-goog-api-key" ) ;
129
+ if ( ! _useHeaderApiKey )
130
+ {
131
+ Client . DefaultRequestHeaders . Add ( "x-goog-api-key" , _apiKey ) ;
132
+ }
133
+ _useHeaderApiKey = Client . DefaultRequestHeaders . Contains ( "x-goog-api-key" ) ;
134
+ }
135
+ }
136
+ }
137
+
120
138
public string ? AccessToken
121
139
{
122
- get => _accessToken ;
123
140
set
124
141
{
125
142
_accessToken = value ;
126
143
if ( value != null )
127
144
Client . DefaultRequestHeaders . Authorization = new AuthenticationHeaderValue ( "Bearer" , _accessToken ) ;
128
145
}
129
146
}
147
+
148
+ public string ? ProjectId
149
+ {
150
+ set
151
+ {
152
+ _projectId = value ;
153
+ if ( ! string . IsNullOrEmpty ( _projectId ) )
154
+ {
155
+ _useHeaderProjectId = Client . DefaultRequestHeaders . Contains ( "x-goog-user-project" ) ;
156
+ if ( ! _useHeaderProjectId )
157
+ {
158
+ Client . DefaultRequestHeaders . Add ( "x-goog-user-project" , _projectId ) ;
159
+ }
160
+ _useHeaderProjectId = Client . DefaultRequestHeaders . Contains ( "x-goog-user-project" ) ;
161
+ }
162
+ }
163
+ }
130
164
131
- // Todo: Integrate Google.Apis.Auth to retrieve Access_Token on demand.
132
- // Todo: Integrate Application Default Credentials as an alternative.
133
- // Reference: https://cloud.google.com/docs/authentication
165
+ /// <summary>
166
+ /// Default constructor attempts to read environment variables and
167
+ /// sets default values, if available
168
+ /// </summary>
134
169
public GenerativeModel ( )
135
170
{
136
171
_options = DefaultJsonSerializerOptions ( ) ;
137
- _model = Environment . GetEnvironmentVariable ( "GOOGLE_AI_MODEL" ) ??
138
- Model . Gemini10Pro ;
139
- _apiKey = Environment . GetEnvironmentVariable ( "GOOGLE_API_KEY" ) ;
140
- _projectId = Environment . GetEnvironmentVariable ( "GOOGLE_PROJECT_ID" ) ;
141
- _region = Environment . GetEnvironmentVariable ( "GOOGLE_REGION" ) ;
142
- AccessToken = Environment . GetEnvironmentVariable ( "GOOGLE_ACCESS_TOKEN" ) ??
143
- GetAccessTokenFromAdc ( ) ;
144
-
172
+ GenerativeModelExtensions . ReadDotEnv ( ) ;
145
173
var credentialsFile =
146
174
Environment . GetEnvironmentVariable ( "GOOGLE_APPLICATION_CREDENTIALS" ) ??
147
175
Environment . GetEnvironmentVariable ( "GOOGLE_WEB_CREDENTIALS" ) ??
148
176
Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) , "gcloud" ,
149
- "application_default_credentials.json" ) ;
150
- if ( File . Exists ( credentialsFile ) )
151
- {
152
- using ( var stream = new FileStream ( credentialsFile , FileMode . Open , FileAccess . Read ) )
153
- {
154
- var json = JsonSerializer . DeserializeAsync < JsonElement > ( stream , _options ) . Result ;
155
- _projectId ??= json . GetValue ( "quota_project_id" ) ??
156
- json . GetValue ( "project_id" ) ;
157
- }
158
- } //var credentials = GoogleCredential.FromFile()
177
+ "application_default_credentials.json" ) ;
178
+ var credentials = GetCredentialsFromFile ( credentialsFile ) ;
179
+
180
+ ApiKey = Environment . GetEnvironmentVariable ( "GOOGLE_API_KEY" ) ;
181
+ AccessToken = Environment . GetEnvironmentVariable ( "GOOGLE_ACCESS_TOKEN" ) ;
182
+ ProjectId = Environment . GetEnvironmentVariable ( "GOOGLE_PROJECT_ID" ) ??
183
+ credentials ? . ProjectId ;
184
+ _model = Environment . GetEnvironmentVariable ( "GOOGLE_AI_MODEL" ) ??
185
+ Model . Gemini10Pro ;
186
+ _region = Environment . GetEnvironmentVariable ( "GOOGLE_REGION" ) ?? _region ;
159
187
}
160
188
161
- // Todo: Add parameters for GenerationConfig, SafetySettings, Transport? and Tools
162
189
/// <summary>
163
190
/// Constructor to initialize access to Google AI Gemini API.
164
191
/// </summary>
@@ -171,20 +198,10 @@ public GenerativeModel(string? apiKey = null,
171
198
GenerationConfig ? generationConfig = null ,
172
199
List < SafetySetting > ? safetySettings = null ) : this ( )
173
200
{
174
- _apiKey = apiKey ?? _apiKey ;
175
- _model = model . SanitizeModelName ( ) ?? _model ;
201
+ ApiKey = apiKey ?? _apiKey ;
202
+ _model = model ? . SanitizeModelName ( ) ?? _model ;
176
203
_generationConfig ??= generationConfig ;
177
204
_safetySettings ??= safetySettings ;
178
-
179
- if ( ! string . IsNullOrEmpty ( apiKey ) )
180
- {
181
- _useHeaderApiKey = Client . DefaultRequestHeaders . Contains ( "x-goog-api-key" ) ;
182
- if ( ! _useHeaderApiKey )
183
- {
184
- Client . DefaultRequestHeaders . Add ( "x-goog-api-key" , _apiKey ) ;
185
- }
186
- _useHeaderApiKey = Client . DefaultRequestHeaders . Contains ( "x-goog-api-key" ) ;
187
- }
188
205
}
189
206
190
207
/// <summary>
@@ -195,27 +212,19 @@ public GenerativeModel(string? apiKey = null,
195
212
/// <param name="model">Model to use</param>
196
213
/// <param name="generationConfig"></param>
197
214
/// <param name="safetySettings"></param>
198
- internal GenerativeModel ( string projectId , string region ,
199
- string model = Model . Gemini10Pro ,
215
+ internal GenerativeModel ( string ? projectId = null , string ? region = null ,
216
+ string ? model = null ,
200
217
GenerationConfig ? generationConfig = null ,
201
218
List < SafetySetting > ? safetySettings = null ) : this ( )
202
219
{
203
220
_useVertexAi = true ;
204
- _projectId = projectId ;
205
- _region = region ;
206
- _model = model . SanitizeModelName ( ) ;
221
+ AccessToken = Environment . GetEnvironmentVariable ( "GOOGLE_ACCESS_TOKEN" ) ??
222
+ GetAccessTokenFromAdc ( ) ;
223
+ ProjectId = projectId ?? _projectId ;
224
+ _region = region ?? _region ;
225
+ _model = model ? . SanitizeModelName ( ) ?? _model ;
207
226
_generationConfig = generationConfig ;
208
227
_safetySettings = safetySettings ;
209
-
210
- if ( ! string . IsNullOrEmpty ( projectId ) )
211
- {
212
- _useHeaderProjectId = Client . DefaultRequestHeaders . Contains ( "x-goog-user-project" ) ;
213
- if ( ! _useHeaderProjectId )
214
- {
215
- Client . DefaultRequestHeaders . Add ( "x-goog-user-project" , _projectId ) ;
216
- }
217
- _useHeaderProjectId = Client . DefaultRequestHeaders . Contains ( "x-goog-user-project" ) ;
218
- }
219
228
}
220
229
221
230
/// <summary>
@@ -643,6 +652,32 @@ internal JsonSerializerOptions DefaultJsonSerializerOptions()
643
652
return options ;
644
653
}
645
654
655
+ /// <summary>
656
+ ///
657
+ /// </summary>
658
+ /// <param name="credentialsFile"></param>
659
+ /// <returns></returns>
660
+ private Credentials ? GetCredentialsFromFile ( string credentialsFile )
661
+ {
662
+ Credentials ? credentials = null ;
663
+ if ( File . Exists ( credentialsFile ) )
664
+ {
665
+ var options = DefaultJsonSerializerOptions ( ) ;
666
+ options . PropertyNamingPolicy = JsonNamingPolicy . SnakeCaseLower ;
667
+ using ( var stream = new FileStream ( credentialsFile , FileMode . Open , FileAccess . Read ) )
668
+ {
669
+ credentials = JsonSerializer . Deserialize < Credentials > ( stream , options ) ;
670
+ }
671
+ }
672
+
673
+ return credentials ;
674
+ }
675
+
676
+ /// <summary>
677
+ /// Retrieve access token from Application Default Credentials (ADC)
678
+ /// </summary>
679
+ /// <returns>The access token.</returns>
680
+ // Reference: https://cloud.google.com/docs/authentication
646
681
private string GetAccessTokenFromAdc ( )
647
682
{
648
683
if ( System . Runtime . InteropServices . RuntimeInformation . IsOSPlatform ( System . Runtime . InteropServices . OSPlatform . Windows ) )
0 commit comments