Skip to content

Commit

Permalink
Merge pull request #43 from mscraftsman/logging
Browse files Browse the repository at this point in the history
Feature suggestion: Add logs with LogLevel using the Standard logging in .NET
jochenkirstaetter authored Oct 30, 2024
2 parents f3bbd4e + 3763c88 commit aa52b71
Showing 19 changed files with 293 additions and 469 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -396,3 +396,4 @@ FodyWeavers.xsd
**/appsettings.Development.json
**/client_secret*.json
*.p12
*.DotSettings
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ Alternatively, add the following line to your `.csproj` file.

```text
<ItemGroup>
<PackageReference Include="Mscc.GenerativeAI" Version="1.8.0" />
<PackageReference Include="Mscc.GenerativeAI" Version="1.8.1" />
</ItemGroup>
```

2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.0
1.8.1
6 changes: 6 additions & 0 deletions src/Mscc.GenerativeAI.Google/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
### Fixed

## 1.8.1

### Changed

- bump version

## 1.8.0

### Changed
6 changes: 6 additions & 0 deletions src/Mscc.GenerativeAI.Web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
### Fixed

## 1.8.1

### Changed

- bump version

## 1.8.0

### Changed
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
using System.Text.Json.Serialization;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Net;
using System.Net.Http.Headers;
@@ -16,19 +17,18 @@

namespace Mscc.GenerativeAI
{
public abstract class BaseGeneration
public abstract class BaseModel : BaseLogger
{
private const string EndpointGoogleAi = "https://generativelanguage.googleapis.com";
protected const string EndpointGoogleAi = "https://generativelanguage.googleapis.com";

protected readonly string _region = "us-central1";
protected readonly string _publisher = "google";

Check warning on line 24 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_publisher' is not CLS-compliant
protected readonly JsonSerializerOptions _options;

Check warning on line 25 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_options' is not CLS-compliant
internal readonly Credentials? _credentials;

protected string _model;

Check warning on line 27 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_model' is not CLS-compliant
protected string? _apiKey;

Check warning on line 28 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_apiKey' is not CLS-compliant
protected string? _accessToken;

Check warning on line 29 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_accessToken' is not CLS-compliant
protected string? _projectId;

Check warning on line 30 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_projectId' is not CLS-compliant
protected string _region = "us-central1";

Check warning on line 31 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_region' is not CLS-compliant

#if NET472_OR_GREATER || NETSTANDARD2_0
protected static readonly Version _httpVersion = HttpVersion.Version11;

Check warning on line 34 in src/Mscc.GenerativeAI/BaseModel.cs

GitHub Actions / Build, pack and push to GitHub Package Registry (GPR) (ubuntu-latest, 8.x)

Identifier '_httpVersion' is not CLS-compliant
@@ -85,6 +85,19 @@ public string? ApiKey
}
}

/// <summary>
/// Sets the access token to use for the request.
/// </summary>
public string? AccessToken
{
set
{
_accessToken = value;
if (value != null)
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);
}
}

/// <summary>
/// Sets the project ID to use for the request.
/// </summary>
@@ -106,18 +119,14 @@ public string? ProjectId
}
}
}

/// <summary>
/// Sets the access token to use for the request.
/// Returns the region to use for the request.
/// </summary>
public string? AccessToken
public string Region
{
set
{
_accessToken = value;
if (value != null)
Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);
}
get => _region;
set => _region = value;
}

/// <summary>
@@ -129,32 +138,42 @@ public TimeSpan Timeout
set => Client.Timeout = value;
}

public BaseGeneration()
/// <summary>
///
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
public BaseModel(ILogger? logger = null) : base(logger)
{
_options = DefaultJsonSerializerOptions();
GenerativeAIExtensions.ReadDotEnv();
var credentialsFile =
Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS") ??
Environment.GetEnvironmentVariable("GOOGLE_WEB_CREDENTIALS") ??
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "gcloud",
"application_default_credentials.json");
_credentials = GetCredentialsFromFile(credentialsFile);

ApiKey = Environment.GetEnvironmentVariable("GOOGLE_API_KEY");
AccessToken = Environment.GetEnvironmentVariable("GOOGLE_ACCESS_TOKEN"); // ?? GetAccessTokenFromAdc();
Model = Environment.GetEnvironmentVariable("GOOGLE_AI_MODEL") ??
GenerativeAI.Model.Gemini15Pro;
_region = Environment.GetEnvironmentVariable("GOOGLE_REGION") ?? _region;
}

public BaseGeneration(string? projectId = null, string? region = null,
string? model = null) : this()
/// <summary>
///
/// </summary>
/// <param name="projectId"></param>
/// <param name="region"></param>
/// <param name="model"></param>
/// <param name="logger">Optional. Logger instance used for logging</param>
public BaseModel(string? projectId = null, string? region = null,
string? model = null, ILogger? logger = null) : this(logger)
{
AccessToken = Environment.GetEnvironmentVariable("GOOGLE_ACCESS_TOKEN") ??
var credentialsFile =
Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS") ??
Environment.GetEnvironmentVariable("GOOGLE_WEB_CREDENTIALS") ??
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "gcloud",
"application_default_credentials.json");
var credentials = GetCredentialsFromFile(credentialsFile);
AccessToken = _accessToken ??
GetAccessTokenFromAdc();
ProjectId = projectId ??
Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID") ??
_credentials?.ProjectId ??
credentials?.ProjectId ??
_projectId;
_region = region ?? _region;
Model = model ?? _model;
@@ -318,7 +337,7 @@ private string RunExternalExe(string filename, string arguments)
}
catch (Exception e)
{
// throw new Exception("OS error while executing " + Format(filename, arguments)+ ": " + e.Message, e);
Logger.LogRunExternalExe("OS error while executing " + Format(filename, arguments)+ ": " + e.Message);
return string.Empty;
}

5 changes: 4 additions & 1 deletion src/Mscc.GenerativeAI/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -10,14 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Feature suggestion: Retry mechanism ([#2](https://github.com/mscraftsman/generative-ai/issues/2))
- Feature suggestion: Add logs with LogLevel using the Standard logging in .NET ([#6](https://github.com/mscraftsman/generative-ai/issues/6))
- implement Automatic Function Call (AFC)

### Changed
### Fixed

## 1.8.1

### Added

- add logs with LogLevel using the Standard logging in .NET ([#6](https://github.com/mscraftsman/generative-ai/issues/6)) - thanks @doggy8088

### Changed

- improve regarding XMLdoc, typos, and non-nullable properties
16 changes: 10 additions & 6 deletions src/Mscc.GenerativeAI/CachedContentModel.cs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;
using System.Text;

namespace Mscc.GenerativeAI
@@ -14,17 +15,20 @@ namespace Mscc.GenerativeAI
/// Content that has been preprocessed and can be used in subsequent request to GenerativeService.
/// Cached content can be only used with model it was created for.
/// </summary>
public class CachedContentModel : BaseGeneration
public sealed class CachedContentModel : BaseModel
{
protected override string Version => ApiVersion.V1Beta;
private const string EndpointGoogleAi = "https://generativelanguage.googleapis.com";

/// <summary>
///
/// Initializes a new instance of the <see cref="CachedContentModel"/> class.
/// </summary>
public CachedContentModel()
{
}
public CachedContentModel() : this(logger: null) { }

/// <summary>
/// Initializes a new instance of the <see cref="CachedContentModel"/> class.
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
public CachedContentModel(ILogger? logger = null) : base(logger) { }

/// <summary>
/// Creates CachedContent resource.
21 changes: 13 additions & 8 deletions src/Mscc.GenerativeAI/FilesModel.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
#if NET472_OR_GREATER || NETSTANDARD2_0
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;

namespace Mscc.GenerativeAI
{
public class FilesModel : BaseGeneration
public sealed class FilesModel : BaseModel
{
protected override string Version => ApiVersion.V1Beta;
private const string EndpointGoogleAi = "https://generativelanguage.googleapis.com";

/// <summary>
/// Initializes a new instance of the <see cref="FilesModel"/> class.
/// </summary>
public FilesModel() : this(logger: null) { }

/// <summary>
/// Initializes a new instance of the <see cref="FilesModel"/> class.
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
public FilesModel(ILogger? logger) : base(logger) { }

/// <summary>
/// Lists the metadata for Files owned by the requesting project.
454 changes: 68 additions & 386 deletions src/Mscc.GenerativeAI/GenerativeModel.cs

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions src/Mscc.GenerativeAI/GoogleAI.cs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;

namespace Mscc.GenerativeAI
{
@@ -15,7 +16,7 @@ namespace Mscc.GenerativeAI
/// <remarks>
/// See <a href="https://ai.google.dev/api/rest">Model reference</a>.
/// </remarks>
public sealed class GoogleAI : IGenerativeAI
public sealed class GoogleAI : BaseLogger, IGenerativeAI
{
private readonly string? _apiKey;
private readonly string? _accessToken;
@@ -36,7 +37,7 @@ public sealed class GoogleAI : IGenerativeAI
/// <description>Optional. Access token provided by OAuth 2.0 or Application Default Credentials (ADC).</description></item>
/// </list>
/// </remarks>
private GoogleAI()
private GoogleAI(ILogger? logger = null) : base(logger)
{
GenerativeAIExtensions.ReadDotEnv();
_apiKey = Environment.GetEnvironmentVariable("GOOGLE_API_KEY");
@@ -49,7 +50,8 @@ private GoogleAI()
/// </summary>
/// <param name="apiKey">Identifier of the Google Cloud project</param>
/// <param name="accessToken">Access token for the Google Cloud project</param>
public GoogleAI(string? apiKey = null, string? accessToken = null) : this()
/// <param name="logger">Optional. Logger instance used for logging</param>
public GoogleAI(string? apiKey = null, string? accessToken = null, ILogger? logger = null) : this(logger)
{
_apiKey ??= apiKey;
_accessToken ??= accessToken;
15 changes: 10 additions & 5 deletions src/Mscc.GenerativeAI/ImageGenerationModel.cs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;
using System.Text;

namespace Mscc.GenerativeAI
@@ -12,32 +13,36 @@ namespace Mscc.GenerativeAI
/// Name of the model that supports image generation.
/// The <see cref="ImageGenerationModel"/> can create high quality visual assets in seconds and brings Google's state-of-the-art vision and multimodal generative AI capabilities to application developers.
/// </summary>
public class ImageGenerationModel : BaseGeneration
public sealed class ImageGenerationModel : BaseModel
{
private const string UrlVertexAi =
"https://{region}-aiplatform.googleapis.com/{version}/projects/{projectId}/locations/{region}/publishers/{publisher}/models/{model}:{method}";

private string Url => UrlVertexAi;

private string Method => GenerativeAI.Method.Predict;

/// <summary>
/// Initializes a new instance of the <see cref="ImageGenerationModel"/> class.
/// </summary>
public ImageGenerationModel() : this(logger: null) { }

/// <summary>
/// Initializes a new instance of the <see cref="ImageGenerationModel"/> class.
/// The default constructor attempts to read <c>.env</c> file and environment variables.
/// Sets default values, if available.
/// </summary>
public ImageGenerationModel() { }
public ImageGenerationModel(ILogger? logger = null) : base(logger) { }

/// <summary>
/// Initializes a new instance of the <see cref="ImageGenerationModel"/> class with access to Vertex AI Gemini API.
/// </summary>
/// <param name="projectId">Identifier of the Google Cloud project</param>
/// <param name="region">Region to use</param>
/// <param name="model">Model to use</param>
/// <param name="logger">Optional. Logger instance used for logging</param>
public ImageGenerationModel(string? projectId = null, string? region = null,
string? model = null) : base(projectId, region, model)
{
}
string? model = null, ILogger? logger = null) : base(projectId, region, model, logger) { }

/// <summary>
/// Generates images from the specified <see cref="ImageGenerationRequest"/>.
15 changes: 10 additions & 5 deletions src/Mscc.GenerativeAI/ImageTextModel.cs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;
using System.Text;

namespace Mscc.GenerativeAI
@@ -12,32 +13,36 @@ namespace Mscc.GenerativeAI
/// Name of the model that supports image captioning.
/// <see cref="ImageTextModel"/> generates a caption from an image you provide based on the language that you specify. The model supports the following languages: English (en), German (de), French (fr), Spanish (es) and Italian (it).
/// </summary>
public class ImageTextModel : BaseGeneration
public sealed class ImageTextModel : BaseModel
{
private const string UrlVertexAi =
"https://{region}-aiplatform.googleapis.com/{version}/projects/{projectId}/locations/{region}/publishers/{publisher}/models/{model}:{method}";

private string Url => UrlVertexAi;

private string Method => GenerativeAI.Method.Predict;

/// <summary>
/// Initializes a new instance of the <see cref="ImageTextModel"/> class.
/// </summary>
public ImageTextModel() : this(logger: null) { }

/// <summary>
/// Initializes a new instance of the <see cref="ImageTextModel"/> class.
/// The default constructor attempts to read <c>.env</c> file and environment variables.
/// Sets default values, if available.
/// </summary>
public ImageTextModel() { }
public ImageTextModel(ILogger? logger = null) : base(logger) { }

/// <summary>
/// Initializes a new instance of the <see cref="ImageTextModel"/> class with access to Vertex AI Gemini API.
/// </summary>
/// <param name="projectId">Identifier of the Google Cloud project</param>
/// <param name="region">Region to use</param>
/// <param name="model">Model to use</param>
/// <param name="logger">Optional. Logger instance used for logging</param>
public ImageTextModel(string? projectId = null, string? region = null,
string? model = null) : base(projectId, region, model)
{
}
string? model = null, ILogger? logger = null) : base(projectId, region, model, logger) { }

/// <summary>
/// Generates images from the specified <see cref="ImageTextRequest"/>.
58 changes: 58 additions & 0 deletions src/Mscc.GenerativeAI/Logging/GenerativeModelLogMessages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;

namespace Mscc.GenerativeAI
{
#pragma warning disable SYSLIB1006 // Multiple logging methods cannot use the same event id within a class

/// <summary>
/// Extensions for logging <see cref="GenerativeModel"/> invocations.
/// </summary>
/// <remarks>
/// This extension uses the <see cref="LoggerMessageAttribute"/> to
/// generate logging code at compile time to achieve optimized code.
/// </remarks>
[ExcludeFromCodeCoverage]
internal static partial class GenerativeModelLogMessages
{
/// <summary>
/// Logs <see cref="GenerativeModel"/>
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "Generative model starting")]
public static partial void LogGenerativeModelInvoking(
this ILogger logger);

/// <summary>
/// Logs <see cref="GenerativeModel"/>
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
[LoggerMessage(EventId = 0, Level = LogLevel.Information, Message = "Generative model started")]
public static partial void LogGenerativeModelInvoked(
this ILogger logger);

/// <summary>
/// Logs <see cref="GenerativeModel"/> invoking an API request.
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
/// <param name="methodName">Calling method</param>
/// <param name="url">URL of Gemini API endpoint</param>
/// <param name="payload">Data sent to the API endpoint</param>
[LoggerMessage(EventId = 0, Level = LogLevel.Debug, Message = "[{MethodName}] Request: {Url} - {Payload}")]
public static partial void LogGenerativeModelInvokingRequest(
this ILogger logger,
string methodName,
string url,
string payload);

/// <summary>
/// Logs <see cref="BaseModel"/> when exception thrown to run an external application.
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
/// <param name="message">Message of <see cref="System.Exception"/> to log.</param>
[LoggerMessage(EventId = 0, Level = LogLevel.Warning, Message = "{Message}")]
public static partial void LogRunExternalExe(
this ILogger logger,
string message);
}
}
46 changes: 26 additions & 20 deletions src/Mscc.GenerativeAI/MediaModel.cs
Original file line number Diff line number Diff line change
@@ -2,24 +2,31 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Authentication;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;
using System.Net.Http.Headers;
using System.Text;

namespace Mscc.GenerativeAI
{
public class MediaModel : BaseGeneration
public sealed class MediaModel : BaseModel
{
protected override string Version => ApiVersion.V1Beta;
private const string EndpointGoogleAi = "https://generativelanguage.googleapis.com";

/// <summary>
/// Initializes a new instance of the <see cref="MediaModel"/> class.
/// </summary>
public MediaModel() : this(logger: null) { }

/// <summary>
/// Initializes a new instance of the <see cref="MediaModel"/> class.
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
public MediaModel(ILogger? logger) : base(logger) { }

/// <summary>
/// Uploads a file to the File API backend.
/// </summary>
@@ -68,21 +75,20 @@ public async Task<UploadMediaResponse> UploadFile(string uri,
});
string json = Serialize(request);

using (var fs = new FileStream(uri, FileMode.Open)){
var multipartContent = new MultipartContent("related");
multipartContent.Add(new StringContent(json, Encoding.UTF8, Constants.MediaType));
multipartContent.Add(new StreamContent(fs, (int)Constants.ChunkSize)
{
Headers = {
ContentType = new MediaTypeHeaderValue(mimeType),
ContentLength = totalBytes
}
});
using var fs = new FileStream(uri, FileMode.Open);
var multipartContent = new MultipartContent("related");
multipartContent.Add(new StringContent(json, Encoding.UTF8, Constants.MediaType));
multipartContent.Add(new StreamContent(fs, (int)Constants.ChunkSize)
{
Headers = {
ContentType = new MediaTypeHeaderValue(mimeType),
ContentLength = totalBytes
}
});

var response = await Client.PostAsync(url, multipartContent, cancellationToken);
await response.EnsureSuccessAsync();
return await Deserialize<UploadMediaResponse>(response);
}
var response = await Client.PostAsync(url, multipartContent, cancellationToken);
await response.EnsureSuccessAsync();
return await Deserialize<UploadMediaResponse>(response);
}

/// <summary>
1 change: 1 addition & 0 deletions src/Mscc.GenerativeAI/Mscc.GenerativeAI.csproj
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>

19 changes: 19 additions & 0 deletions src/Mscc.GenerativeAI/Types/BaseLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

namespace Mscc.GenerativeAI
{
/// <summary>
/// Abstract base type with logging instance.
/// </summary>
public abstract class BaseLogger
{
protected ILogger Logger { get; }

/// <summary>
/// Base constructor to set the <see cref="ILogger"/> instance.
/// </summary>
/// <param name="logger">Optional. Logger instance used for logging</param>
protected BaseLogger(ILogger? logger) => Logger = logger ?? NullLogger.Instance;
}
}
6 changes: 3 additions & 3 deletions src/Mscc.GenerativeAI/Types/Generative/Credentials.cs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ namespace Mscc.GenerativeAI
/// It de/serializes the content of the client_secret.json file for OAuth 2.0
/// using either Desktop or Web approach, and supports Service Accounts on Google Cloud Platform.
/// </summary>
internal class Credentials : ClientSecrets
public sealed class Credentials : ClientSecrets
{
private string _projectId;

@@ -47,7 +47,7 @@ public string ProjectId
/// <summary>
/// Project ID (quota) in Google Cloud Platform.
/// </summary>
public virtual string QuotaProjectId
public string QuotaProjectId
{
get => _projectId;
set => _projectId = value;
@@ -58,7 +58,7 @@ public virtual string QuotaProjectId
/// Represents the content of a client_secret.json file used in Google Cloud Platform
/// to authenticate a user or service account.
/// </summary>
internal class ClientSecrets
public class ClientSecrets
{
/// <summary>
/// Client ID
10 changes: 6 additions & 4 deletions src/Mscc.GenerativeAI/VertexAI.cs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
#endif
using Microsoft.Extensions.Logging;

namespace Mscc.GenerativeAI
{
@@ -13,7 +14,7 @@ namespace Mscc.GenerativeAI
/// See <a href="https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/overview">Model reference</a>.
/// See also https://cloud.google.com/nodejs/docs/reference/vertexai/latest/vertexai/vertexinit
/// </remarks>
public sealed class VertexAI : IGenerativeAI
public sealed class VertexAI : BaseLogger, IGenerativeAI
{
private readonly string? _projectId;
private readonly string _region = "us-central1";
@@ -36,7 +37,7 @@ public sealed class VertexAI : IGenerativeAI
/// <description>Identifier of the Google Cloud region to use (default: "us-central1").</description></item>
/// </list>
/// </remarks>
private VertexAI()
private VertexAI(ILogger? logger = null) : base(logger)
{
GenerativeAIExtensions.ReadDotEnv();
_projectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID");
@@ -47,9 +48,10 @@ private VertexAI()
/// Initializes a new instance of the <see cref="VertexAI"/> class with access to Vertex AI Gemini API.
/// </summary>
/// <param name="projectId">Identifier of the Google Cloud project.</param>
/// <param name="region">Region to use (default: "us-central1").</param>
/// <param name="region">Optional. Region to use (default: "us-central1").</param>
/// <param name="logger">Optional. Logger instance used for logging</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="projectId"/> is <see langword="null"/>.</exception>
public VertexAI(string? projectId, string? region = null) : this()
public VertexAI(string? projectId, string? region = null, ILogger? logger = null) : this(logger)
{
_projectId ??= projectId ?? throw new ArgumentNullException(nameof(projectId));
_region = region ?? _region;

0 comments on commit aa52b71

Please sign in to comment.