diff --git a/src/Mscc.GenerativeAI.Microsoft/GeminiChatClient.cs b/src/Mscc.GenerativeAI.Microsoft/GeminiChatClient.cs index ec8bb40..b3e9c46 100644 --- a/src/Mscc.GenerativeAI.Microsoft/GeminiChatClient.cs +++ b/src/Mscc.GenerativeAI.Microsoft/GeminiChatClient.cs @@ -4,14 +4,14 @@ using System.Threading; using System.Threading.Tasks; #endif -using Microsoft.Extensions.AI; +using mea = Microsoft.Extensions.AI; using System.Runtime.CompilerServices; namespace Mscc.GenerativeAI.Microsoft; -public sealed class GeminiChatClient : IChatClient +public sealed class GeminiChatClient : mea.IChatClient { - private const string providerName = "gemini"; + private const string ProviderName = "gemini"; /// /// Gets the Gemini model that is used to communicate with. @@ -19,7 +19,7 @@ public sealed class GeminiChatClient : IChatClient private readonly GenerativeModel _client; /// - public ChatClientMetadata Metadata { get; } + public mea.ChatClientMetadata Metadata { get; } /// /// Creates an instance of the Gemini API client. @@ -30,13 +30,13 @@ public GeminiChatClient(string apiKey, string model = "") { var genAi = new GoogleAI(apiKey); _client = genAi.GenerativeModel(model); - Metadata = new(providerName, null, model); + Metadata = new(ProviderName, null, model); } /// - public async Task CompleteAsync( - IList chatMessages, - ChatOptions? options = null, + public async Task CompleteAsync( + IList chatMessages, + mea.ChatOptions? options = null, CancellationToken cancellationToken = default) { if (chatMessages == null) throw new ArgumentNullException(nameof(chatMessages)); @@ -44,13 +44,13 @@ public async Task CompleteAsync( var request = MicrosoftAi.AbstractionMapper.ToGeminiGenerateContentRequest(chatMessages, options); var requestOptions = MicrosoftAi.AbstractionMapper.ToGeminiGenerateContentRequestOptions(options); var response = await _client.GenerateContent(request, requestOptions); - return MicrosoftAi.AbstractionMapper.ToChatCompletion(response) ?? new ChatCompletion([]); + return MicrosoftAi.AbstractionMapper.ToChatCompletion(response) ?? new mea.ChatCompletion([]); } /// - public async IAsyncEnumerable CompleteStreamingAsync( - IList chatMessages, - ChatOptions? options = null, + public async IAsyncEnumerable CompleteStreamingAsync( + IList chatMessages, + mea.ChatOptions? options = null, [EnumeratorCancellation] CancellationToken cancellationToken = default) { if (chatMessages == null) throw new ArgumentNullException(nameof(chatMessages)); diff --git a/src/Mscc.GenerativeAI.Microsoft/MicrosoftAi/AbstractionMapper.cs b/src/Mscc.GenerativeAI.Microsoft/MicrosoftAi/AbstractionMapper.cs index 1aeb8d1..3d2a447 100644 --- a/src/Mscc.GenerativeAI.Microsoft/MicrosoftAi/AbstractionMapper.cs +++ b/src/Mscc.GenerativeAI.Microsoft/MicrosoftAi/AbstractionMapper.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; #endif -using Microsoft.Extensions.AI; +using mea = Microsoft.Extensions.AI; namespace Mscc.GenerativeAI.Microsoft.MicrosoftAi { @@ -18,9 +18,9 @@ public static class AbstractionMapper /// A list of chat messages. /// Optional. Chat options to configure the request. /// - public static GenerateContentRequest? ToGeminiGenerateContentRequest(IList chatMessages, ChatOptions? options) + public static GenerateContentRequest? ToGeminiGenerateContentRequest(IList chatMessages, mea.ChatOptions? options) { - var prompt = string.Join(" ", chatMessages.ToArray()) ?? ""; + var prompt = string.Join(" ", chatMessages.ToArray()) ?? ""; GenerationConfig? generationConfig = null; if (options?.AdditionalProperties?.Any() ?? false) @@ -47,11 +47,11 @@ public static class AbstractionMapper } /// - /// Converts a to a . + /// Converts a to a . /// /// Chat options to configure the request. /// - public static RequestOptions? ToGeminiGenerateContentRequestOptions(ChatOptions? options) + public static RequestOptions? ToGeminiGenerateContentRequestOptions(mea.ChatOptions? options) { if (options is null) return null; @@ -79,7 +79,7 @@ public static class AbstractionMapper /// /// The values to get embeddings for /// The options for the embeddings - public static EmbedContentRequest ToGeminiEmbedContentRequest(IEnumerable values, EmbeddingGenerationOptions? options) + public static EmbedContentRequest ToGeminiEmbedContentRequest(IEnumerable values, mea.EmbeddingGenerationOptions? options) { return new EmbedContentRequest(string.Join(" ", values)) { @@ -88,17 +88,17 @@ public static EmbedContentRequest ToGeminiEmbedContentRequest(IEnumerable - /// Converts a to a . + /// Converts a to a . /// /// The response with completion data. /// - public static ChatCompletion? ToChatCompletion(GenerateContentResponse? response) + public static mea.ChatCompletion? ToChatCompletion(GenerateContentResponse? response) { if (response is null) return null; var chatMessage = ToChatMessage(response); - return new ChatCompletion(chatMessage) + return new mea.ChatCompletion(chatMessage) { FinishReason = ToFinishReason(response.Candidates?.FirstOrDefault()?.FinishReason), AdditionalProperties = null, @@ -112,35 +112,35 @@ public static EmbedContentRequest ToGeminiEmbedContentRequest(IEnumerable - /// Converts a to a . + /// Converts a to a . /// /// The response stream to convert. - public static StreamingChatCompletionUpdate ToStreamingChatCompletionUpdate(GenerateContentResponse? response) + public static mea.StreamingChatCompletionUpdate ToStreamingChatCompletionUpdate(GenerateContentResponse? response) { - return new StreamingChatCompletionUpdate + return new mea.StreamingChatCompletionUpdate { // no need to set "Contents" as we set the text CompletionId = null, ChoiceIndex = 0, // should be left at 0 as Mscc.GenerativeAI does not support this CreatedAt = null, AdditionalProperties = null, - FinishReason = response?.Candidates?.FirstOrDefault()?.FinishReason == FinishReason.Other ? ChatFinishReason.Stop : null, + FinishReason = response?.Candidates?.FirstOrDefault()?.FinishReason == FinishReason.Other ? mea.ChatFinishReason.Stop : null, RawRepresentation = response, Text = response?.Text, Role = ToAbstractionRole(response?.Candidates?.FirstOrDefault()?.Content?.Role) }; } - public static GeneratedEmbeddings> ToGeneratedEmbeddings(EmbedContentRequest request, EmbedContentResponse response) + public static mea.GeneratedEmbeddings> ToGeneratedEmbeddings(EmbedContentRequest request, EmbedContentResponse response) { if (request == null) throw new ArgumentNullException(nameof(request)); if (response == null) throw new ArgumentNullException(nameof(response)); - AdditionalPropertiesDictionary? responseProps = null; - UsageDetails? usage = null; + mea.AdditionalPropertiesDictionary? responseProps = null; + mea.UsageDetails? usage = null; - return new GeneratedEmbeddings>([ - new Embedding(response.Embedding?.Values.ToArray() ?? []) + return new mea.GeneratedEmbeddings>([ + new mea.Embedding(response.Embedding?.Values.ToArray() ?? []) { CreatedAt = DateTimeOffset.Now, ModelId = request.Model @@ -155,54 +155,54 @@ public static GeneratedEmbeddings> ToGeneratedEmbeddings(EmbedC /// Maps a to a . /// /// The response to map. - private static ChatMessage ToChatMessage(GenerateContentResponse response) + private static mea.ChatMessage ToChatMessage(GenerateContentResponse response) { - var contents = new List(); + var contents = new List(); if (response.Text?.Length > 0) - contents.Insert(0, new TextContent(response.Text)); + contents.Insert(0, new mea.TextContent(response.Text)); - return new ChatMessage(ToAbstractionRole(response.Candidates?.FirstOrDefault()?.Content?.Role), contents) + return new mea.ChatMessage(ToAbstractionRole(response.Candidates?.FirstOrDefault()?.Content?.Role), contents) { RawRepresentation = response }; } /// - /// Maps a to a . + /// Maps a to a . /// /// The role to map. - private static ChatRole ToAbstractionRole(string? role) + private static mea.ChatRole ToAbstractionRole(string? role) { - if (string.IsNullOrEmpty(role)) return new ChatRole("unknown"); + if (string.IsNullOrEmpty(role)) return new mea.ChatRole("unknown"); return role switch { - Role.User => ChatRole.User, - Role.Model => ChatRole.Assistant, - Role.System => ChatRole.System, - Role.Function => ChatRole.Tool, - _ => new ChatRole(role) + Role.User => mea.ChatRole.User, + Role.Model => mea.ChatRole.Assistant, + Role.System => mea.ChatRole.System, + Role.Function => mea.ChatRole.Tool, + _ => new mea.ChatRole(role) }; } /// - /// Maps a to a . + /// Maps a to a . /// /// The finish reason to map. - private static ChatFinishReason? ToFinishReason(FinishReason? finishReason) + private static mea.ChatFinishReason? ToFinishReason(FinishReason? finishReason) { return finishReason switch { null => null, - FinishReason.MaxTokens => ChatFinishReason.Length, - FinishReason.Stop => ChatFinishReason.Stop, - FinishReason.Safety => ChatFinishReason.ContentFilter, - FinishReason.ProhibitedContent => ChatFinishReason.ContentFilter, - FinishReason.Recitation => ChatFinishReason.ContentFilter, - FinishReason.Spii => ChatFinishReason.ContentFilter, - FinishReason.Blocklist => ChatFinishReason.ContentFilter, - FinishReason.MalformedFunctionCall => ChatFinishReason.ToolCalls, - _ => new ChatFinishReason(Enum.GetName(typeof(FinishReason), finishReason)!) + FinishReason.MaxTokens => mea.ChatFinishReason.Length, + FinishReason.Stop => mea.ChatFinishReason.Stop, + FinishReason.Safety => mea.ChatFinishReason.ContentFilter, + FinishReason.ProhibitedContent => mea.ChatFinishReason.ContentFilter, + FinishReason.Recitation => mea.ChatFinishReason.ContentFilter, + FinishReason.Spii => mea.ChatFinishReason.ContentFilter, + FinishReason.Blocklist => mea.ChatFinishReason.ContentFilter, + FinishReason.MalformedFunctionCall => mea.ChatFinishReason.ToolCalls, + _ => new mea.ChatFinishReason(Enum.GetName(typeof(FinishReason), finishReason)!) }; } @@ -210,8 +210,8 @@ private static ChatRole ToAbstractionRole(string? role) /// Parses usage details from a /// /// The response to parse. - /// A instance containing the parsed usage details. - private static UsageDetails? ParseContentResponseUsage(GenerateContentResponse response) + /// A instance containing the parsed usage details. + private static mea.UsageDetails? ParseContentResponseUsage(GenerateContentResponse response) { if (response.UsageMetadata is null) return null; @@ -230,7 +230,7 @@ private static ChatRole ToAbstractionRole(string? role) /// The Gemini setting to add /// The to set the Gemini option, if available in the chat options /// The type of the option - private static void TryAddOption(ChatOptions chatOptions, string option, Action optionSetter) + private static void TryAddOption(mea.ChatOptions chatOptions, string option, Action optionSetter) { if (chatOptions.AdditionalProperties?.TryGetValue(option, out var value) ?? false) optionSetter((T)value); diff --git a/src/Mscc.GenerativeAI.Microsoft/Mscc.GenerativeAI.Microsoft.csproj b/src/Mscc.GenerativeAI.Microsoft/Mscc.GenerativeAI.Microsoft.csproj index d35ae12..aee07e1 100644 --- a/src/Mscc.GenerativeAI.Microsoft/Mscc.GenerativeAI.Microsoft.csproj +++ b/src/Mscc.GenerativeAI.Microsoft/Mscc.GenerativeAI.Microsoft.csproj @@ -53,7 +53,7 @@ - +