diff --git a/src/Cellm/Models/Client.cs b/src/Cellm/Models/Client.cs index 057b463..5fee856 100644 --- a/src/Cellm/Models/Client.cs +++ b/src/Cellm/Models/Client.cs @@ -2,7 +2,6 @@ using Cellm.AddIn; using Cellm.AddIn.Exceptions; using Cellm.Models.Anthropic; -using Cellm.Models.GoogleAi; using Cellm.Models.Llamafile; using Cellm.Models.OpenAi; using Cellm.Prompts; @@ -37,7 +36,6 @@ public async Task Send(Prompt prompt, string? provider, Uri? baseAddress IModelResponse response = parsedProvider switch { Providers.Anthropic => await _sender.Send(new AnthropicRequest(prompt, provider, baseAddress)), - Providers.GoogleAi => await _sender.Send(new GoogleAiRequest(prompt, provider, baseAddress)), Providers.Llamafile => await _sender.Send(new LlamafileRequest(prompt)), Providers.OpenAi => await _sender.Send(new OpenAiRequest(prompt, provider, baseAddress)), _ => throw new InvalidOperationException($"Provider {parsedProvider} is defined but not implemented") diff --git a/src/Cellm/Models/GoogleAi/GoogleAiConfiguration.cs b/src/Cellm/Models/GoogleAi/GoogleAiConfiguration.cs deleted file mode 100644 index 221acff..0000000 --- a/src/Cellm/Models/GoogleAi/GoogleAiConfiguration.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Cellm.Services.Configuration; - -namespace Cellm.Models.GoogleAi; - -internal class GoogleAiConfiguration : IProviderConfiguration -{ - public Uri BaseAddress { get; init; } - - public string DefaultModel { get; init; } - - public string ApiKey { get; init; } - - public GoogleAiConfiguration() - { - BaseAddress = default!; - DefaultModel = default!; - ApiKey = default!; - } -} \ No newline at end of file diff --git a/src/Cellm/Models/GoogleAi/GoogleAiRequest.cs b/src/Cellm/Models/GoogleAi/GoogleAiRequest.cs deleted file mode 100644 index 9596d0f..0000000 --- a/src/Cellm/Models/GoogleAi/GoogleAiRequest.cs +++ /dev/null @@ -1,5 +0,0 @@ -using Cellm.Prompts; - -namespace Cellm.Models.GoogleAi; - -internal record GoogleAiRequest(Prompt Prompt, string? Provider, Uri? BaseAddress) : IModelRequest; \ No newline at end of file diff --git a/src/Cellm/Models/GoogleAi/GoogleAiRequestHandler.cs b/src/Cellm/Models/GoogleAi/GoogleAiRequestHandler.cs deleted file mode 100644 index 2caca59..0000000 --- a/src/Cellm/Models/GoogleAi/GoogleAiRequestHandler.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Text.Json.Serialization; -using Cellm.AddIn; -using Cellm.AddIn.Exceptions; -using Cellm.Prompts; -using Microsoft.Extensions.Options; - -namespace Cellm.Models.GoogleAi; - -internal class GoogleAiRequestHandler : IModelRequestHandler -{ - private readonly GoogleAiConfiguration _googleAiConfiguration; - private readonly CellmConfiguration _cellmConfiguration; - private readonly HttpClient _httpClient; - private readonly Serde _serde; - - public GoogleAiRequestHandler( - IOptions googleAiConfiguration, - IOptions cellmConfiguration, - HttpClient httpClient, - Serde serde) - { - _googleAiConfiguration = googleAiConfiguration.Value; - _cellmConfiguration = cellmConfiguration.Value; - _httpClient = httpClient; - _serde = serde; - } - - public async Task Handle(GoogleAiRequest request, CancellationToken cancellationToken) - { - string path = $"/v1beta/models/{request.Prompt.Model ?? _googleAiConfiguration.DefaultModel}:generateContent?key={_googleAiConfiguration.ApiKey}"; - var address = request.BaseAddress is null ? new Uri(path, UriKind.Relative) : new Uri(request.BaseAddress, path); - - var json = Serialize(request); - var jsonAsStringContent = new StringContent(json, Encoding.UTF8, "application/json"); - - var response = await _httpClient.PostAsync(address, jsonAsStringContent, cancellationToken); - var responseBodyAsString = await response.Content.ReadAsStringAsync(cancellationToken); - - if (!response.IsSuccessStatusCode) - { - throw new HttpRequestException($"{nameof(GoogleAiRequest)} failed: {responseBodyAsString}", null, response.StatusCode); - } - - return Deserialize(request, responseBodyAsString); - } - - public string Serialize(GoogleAiRequest request) - { - var requestBody = new GoogleAiRequestBody - { - SystemInstruction = new GoogleAiContent - { - Parts = new List { new GoogleAiPart { Text = request.Prompt.SystemMessage } } - }, - Contents = new List - { - new GoogleAiContent - { - Parts = request.Prompt.Messages.Select(x => new GoogleAiPart { Text = x.Content }).ToList() - } - } - }; - - return _serde.Serialize(requestBody, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }); - } - - public GoogleAiResponse Deserialize(GoogleAiRequest request, string response) - { - var responseBody = _serde.Deserialize(response, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }); - - var assistantMessage = responseBody?.Candidates?.SingleOrDefault()?.Content?.Parts?.SingleOrDefault()?.Text ?? throw new CellmException("#EMPTY_RESPONSE?"); - - var assistantPrompt = new PromptBuilder(request.Prompt) - .AddAssistantMessage(assistantMessage) - .Build(); - - return new GoogleAiResponse(assistantPrompt); - } -} diff --git a/src/Cellm/Models/GoogleAi/GoogleAiResponse.cs b/src/Cellm/Models/GoogleAi/GoogleAiResponse.cs deleted file mode 100644 index e8436ea..0000000 --- a/src/Cellm/Models/GoogleAi/GoogleAiResponse.cs +++ /dev/null @@ -1,5 +0,0 @@ -using Cellm.Prompts; - -namespace Cellm.Models.GoogleAi; - -internal record GoogleAiResponse(Prompt Prompt) : IModelResponse; \ No newline at end of file diff --git a/src/Cellm/Models/GoogleAi/Models.cs b/src/Cellm/Models/GoogleAi/Models.cs deleted file mode 100644 index 730b3f6..0000000 --- a/src/Cellm/Models/GoogleAi/Models.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Cellm.Models.GoogleAi; - -public class GoogleAiRequestBody -{ - [JsonPropertyName("system_instruction")] - public GoogleAiContent? SystemInstruction { get; set; } - - public List? Contents { get; set; } -} - -public class GoogleAiResponseBody -{ - public List? Candidates { get; set; } - - public GoogleAiUsageMetadata? UsageMetadata { get; set; } -} - -public class GoogleAiCandidate -{ - public GoogleAiContent? Content { get; set; } - - public string? FinishReason { get; set; } - - public int Index { get; set; } - - public List? SafetyRatings { get; set; } -} - -public class GoogleAiContent -{ - public List? Parts { get; set; } - - public string? Role { get; set; } -} - -public class GoogleAiPart -{ - public string? Text { get; set; } -} - -public class GoogleAiSafetyRating -{ - public string? Category { get; set; } - - public string? Probability { get; set; } -} - -public class GoogleAiUsageMetadata -{ - public int PromptTokenCount { get; set; } - - public int CandidatesTokenCount { get; set; } - - public int TotalTokenCount { get; set; } -} \ No newline at end of file diff --git a/src/Cellm/Models/Providers.cs b/src/Cellm/Models/Providers.cs index 09bbe8e..e0e30fa 100644 --- a/src/Cellm/Models/Providers.cs +++ b/src/Cellm/Models/Providers.cs @@ -3,7 +3,6 @@ public enum Providers { Anthropic, - GoogleAi, Llamafile, OpenAi } diff --git a/src/Cellm/Services/ServiceLocator.cs b/src/Cellm/Services/ServiceLocator.cs index 00136fc..c54a52e 100644 --- a/src/Cellm/Services/ServiceLocator.cs +++ b/src/Cellm/Services/ServiceLocator.cs @@ -3,7 +3,6 @@ using Cellm.AddIn.Exceptions; using Cellm.Models; using Cellm.Models.Anthropic; -using Cellm.Models.GoogleAi; using Cellm.Models.Llamafile; using Cellm.Models.OpenAi; using Cellm.Models.PipelineBehavior; @@ -47,7 +46,6 @@ private static IServiceCollection ConfigureServices(IServiceCollection services) services .Configure(configuration.GetRequiredSection(nameof(CellmConfiguration))) .Configure(configuration.GetRequiredSection(nameof(AnthropicConfiguration))) - .Configure(configuration.GetRequiredSection(nameof(GoogleAiConfiguration))) .Configure(configuration.GetRequiredSection(nameof(OpenAiConfiguration))) .Configure(configuration.GetRequiredSection(nameof(LlamafileConfiguration))) .Configure(configuration.GetRequiredSection(nameof(RateLimiterConfiguration))) @@ -125,15 +123,6 @@ private static IServiceCollection ConfigureServices(IServiceCollection services) anthropicHttpClient.Timeout = TimeSpan.FromHours(1); }).AddResilienceHandler($"{nameof(AnthropicRequestHandler)}ResiliencePipeline", resiliencePipelineConfigurator.ConfigureResiliencePipeline); - var googleAiConfiguration = configuration.GetRequiredSection(nameof(GoogleAiConfiguration)).Get() - ?? throw new NullReferenceException(nameof(GoogleAiConfiguration)); - - services.AddHttpClient, GoogleAiRequestHandler>(googleHttpClient => - { - googleHttpClient.BaseAddress = googleAiConfiguration.BaseAddress; - googleHttpClient.Timeout = TimeSpan.FromHours(1); - }).AddResilienceHandler($"{nameof(GoogleAiRequestHandler)}ResiliencePipeline", resiliencePipelineConfigurator.ConfigureResiliencePipeline); - var openAiConfiguration = configuration.GetRequiredSection(nameof(OpenAiConfiguration)).Get() ?? throw new NullReferenceException(nameof(OpenAiConfiguration)); diff --git a/src/Cellm/appsettings.Local.Google.json b/src/Cellm/appsettings.Local.Google.json new file mode 100644 index 0000000..4cb1770 --- /dev/null +++ b/src/Cellm/appsettings.Local.Google.json @@ -0,0 +1,12 @@ +{ + "OpenAiConfiguration": { + "BaseAddress": "https://generativelanguage.googleapis.com/v1beta/openai/", + "DefaultModel": "gemini-1.5-flash", + "ApiKey": "YOUR_GEMINI_API_KEY" + + }, + "CellmConfiguration": { + "DefaultProvider": "OpenAi", + "HttpTimeoutInSeconds": 30 + } +} diff --git a/src/Cellm/appsettings.Local.GoogleAi.json b/src/Cellm/appsettings.Local.GoogleAi.json deleted file mode 100644 index a9d22de..0000000 --- a/src/Cellm/appsettings.Local.GoogleAi.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "GoogleAiConfiguration": { - "ApiKey": "YOUR_GOOGLEAI_APIKEY" - }, - "CellmConfiguration": { - "DefaultProvider": "GoogleAI", - "HttpTimeoutInSeconds": 30 - } -}