diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj b/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj
index ac68607c..0e0f5784 100644
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj
+++ b/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj
@@ -17,7 +17,6 @@
-
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs
index 7b311886..3382f350 100644
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs
+++ b/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs
@@ -10,7 +10,7 @@ public class GoogleAiPlugin : IBotSharpPlugin
{
public string Id => "962ff441-2b40-4db4-b530-49efb1688a75";
public string Name => "Google AI";
- public string Description => "Making AI helpful for everyone (PaLM 2, Gemini)";
+ public string Description => "Making AI helpful for everyone";
public string IconUrl => "https://vectorseek.com/wp-content/uploads/2021/12/Google-AI-Logo-Vector.png";
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
@@ -20,10 +20,8 @@ public class GoogleAiPlugin : IBotSharpPlugin
return settingService.Bind("GoogleAi");
});
- services.AddScoped();
- services.AddScoped();
- services.AddScoped();
- services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
services.AddScoped();
services.AddScoped();
}
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/GeminiChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs
similarity index 98%
rename from src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/GeminiChatCompletionProvider.cs
rename to src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs
index 60e0ef02..d224fb12 100644
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/GeminiChatCompletionProvider.cs
+++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs
@@ -5,14 +5,13 @@ using BotSharp.Abstraction.Hooks;
using GenerativeAI;
using GenerativeAI.Core;
using GenerativeAI.Types;
-using Google.Ai.Generativelanguage.V1Beta2;
namespace BotSharp.Plugin.GoogleAi.Providers.Chat;
-public class GeminiChatCompletionProvider : IChatCompletion
+public class ChatCompletionProvider : IChatCompletion
{
private readonly IServiceProvider _services;
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
private List renderedInstructions = [];
private string _model;
@@ -21,10 +20,10 @@ public class GeminiChatCompletionProvider : IChatCompletion
public string Model => _model;
private GoogleAiSettings _settings;
- public GeminiChatCompletionProvider(
+ public ChatCompletionProvider(
IServiceProvider services,
GoogleAiSettings googleSettings,
- ILogger logger)
+ ILogger logger)
{
_settings = googleSettings;
_services = services;
@@ -104,7 +103,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
var (prompt, messages) = PrepareOptions(chatClient, agent, conversations);
var response = await chatClient.GenerateContentAsync(messages);
-
+
var candidate = response.Candidates?.First();
var part = candidate?.Content?.Parts?.FirstOrDefault();
var text = part?.Text ?? string.Empty;
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/PalmChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/PalmChatCompletionProvider.cs
deleted file mode 100644
index bec65e17..00000000
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/PalmChatCompletionProvider.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-using BotSharp.Abstraction.Routing;
-using LLMSharp.Google.Palm;
-using LLMSharp.Google.Palm.DiscussService;
-using BotSharp.Abstraction.Hooks;
-
-namespace BotSharp.Plugin.GoogleAi.Providers.Chat;
-
-[Obsolete]
-public class PalmChatCompletionProvider : IChatCompletion
-{
- private readonly IServiceProvider _services;
- private readonly ILogger _logger;
- private List renderedInstructions = [];
-
- private string _model;
-
- public string Provider => "google-palm";
- public string Model => _model;
-
- public PalmChatCompletionProvider(
- IServiceProvider services,
- ILogger logger)
- {
- _services = services;
- _logger = logger;
- }
-
- public async Task GetChatCompletions(Agent agent, List conversations)
- {
- var contentHooks = _services.GetHooks(agent.Id);
-
- // Before chat completion hook
- foreach (var hook in contentHooks)
- {
- await hook.BeforeGenerating(agent, conversations);
- }
-
- var client = ProviderHelper.GetPalmClient(Provider, _model, _services);
- var (prompt, messages, hasFunctions) = PrepareOptions(agent, conversations);
-
- RoleDialogModel msg;
-
- if (hasFunctions)
- {
- // use text completion
- // var response = client.GenerateTextAsync(prompt, null).Result;
- var response = await client.ChatAsync(new PalmChatCompletionRequest
- {
- Context = prompt,
- Messages = messages,
- Temperature = 0.1f
- });
-
- var message = response.Candidates.First();
-
- // check if returns function calling
- var llmResponse = message.Content.JsonContent();
-
- msg = new RoleDialogModel(llmResponse.Role, llmResponse.Content)
- {
- CurrentAgentId = agent.Id,
- FunctionName = llmResponse.FunctionName,
- FunctionArgs = JsonSerializer.Serialize(llmResponse.Args),
- RenderedInstruction = string.Join("\r\n", renderedInstructions)
- };
- }
- else
- {
- var response = await client.ChatAsync(messages, context: prompt, examples: null, options: null);
-
- var message = response.Candidates.First();
-
- // check if returns function calling
- var llmResponse = message.Content.JsonContent();
-
- msg = new RoleDialogModel(llmResponse.Role, llmResponse.Content ?? message.Content)
- {
- CurrentAgentId = agent.Id,
- RenderedInstruction = string.Join("\r\n", renderedInstructions)
- };
- }
-
- // After chat completion hook
- foreach (var hook in contentHooks)
- {
- await hook.AfterGenerated(msg, new TokenStatsModel
- {
- Prompt = prompt,
- Provider = Provider,
- Model = _model
- });
- }
-
- return msg;
- }
-
- private (string, List, bool) PrepareOptions(Agent agent, List conversations)
- {
- var agentService = _services.GetRequiredService();
- var routing = _services.GetRequiredService();
- var router = routing.Router;
-
- // Prepare instruction and functions
- var renderData = agentService.CollectRenderData(agent);
- var (prompt, functions) = agentService.PrepareInstructionAndFunctions(agent, renderData);
- if (!string.IsNullOrWhiteSpace(prompt))
- {
- renderedInstructions.Add(prompt);
- }
-
- var messages = conversations.Select(c => new PalmChatMessage(c.LlmContent, c.Role == AgentRole.User ? "user" : "AI"))
- .ToList();
-
- if (!functions.IsNullOrEmpty())
- {
- prompt += "\r\n\r\n[Functions] defined in JSON Schema:\r\n";
- prompt += JsonSerializer.Serialize(functions, new JsonSerializerOptions
- {
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
- WriteIndented = true
- });
-
- prompt += "\r\n\r\n[Conversations]\r\n";
- foreach (var dialog in conversations)
- {
- prompt += dialog.Role == AgentRole.Function ?
- $"{dialog.Role}: {dialog.FunctionName} => {dialog.LlmContent}\r\n" :
- $"{dialog.Role}: {dialog.LlmContent}\r\n";
- }
-
- prompt += "\r\n\r\n" + router.Templates.FirstOrDefault(x => x.Name == "response_with_function").Content;
-
- return (prompt, new List
- {
- new PalmChatMessage("Which function should be used for the next step based on latest user or function response, output your response in JSON:", AgentRole.User),
- }, true);
- }
-
- return (prompt, messages, false);
- }
-
- public Task GetChatCompletionsAsync(Agent agent, List conversations, Func onMessageReceived, Func onFunctionExecuting)
- {
- throw new NotImplementedException();
- }
-
- public Task GetChatCompletionsStreamingAsync(Agent agent, List conversations)
- {
- throw new NotImplementedException();
- }
-
- public void SetModelName(string model)
- {
- _model = model;
- }
-}
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Image/ImageCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Image/ImageCompletionProvider.cs
new file mode 100644
index 00000000..1ddd71f5
--- /dev/null
+++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Image/ImageCompletionProvider.cs
@@ -0,0 +1,58 @@
+using System.IO;
+
+namespace BotSharp.Plugin.GoogleAI.Providers.Image;
+
+public partial class ImageCompletionProvider : IImageCompletion
+{
+ protected readonly GoogleAiSettings _settings;
+ protected readonly IServiceProvider _services;
+ protected readonly ILogger _logger;
+
+ private const int DEFAULT_IMAGE_COUNT = 1;
+ private const int IMAGE_COUNT_LIMIT = 5;
+
+ protected string _model;
+
+ public virtual string Provider => "google-ai";
+ public string Model => _model;
+
+ public ImageCompletionProvider(
+ GoogleAiSettings settings,
+ ILogger logger,
+ IServiceProvider services)
+ {
+ _settings = settings;
+ _services = services;
+ _logger = logger;
+ }
+
+ public void SetModelName(string model)
+ {
+ _model = model;
+ }
+
+ public Task GetImageGeneration(Agent agent, RoleDialogModel message)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetImageVariation(Agent agent, RoleDialogModel message, Stream image, string imageFileName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetImageEdits(Agent agent, RoleDialogModel message, Stream image, string imageFileName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetImageEdits(Agent agent, RoleDialogModel message, Stream image, string imageFileName, Stream mask, string maskFileName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetImageComposition(Agent agent, RoleDialogModel message, Stream[] images, string[] imageFileNames)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ProviderHelper.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ProviderHelper.cs
index 7b6c25ea..1f907c2b 100644
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ProviderHelper.cs
+++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ProviderHelper.cs
@@ -1,5 +1,3 @@
-using LLMSharp.Google.Palm;
-
namespace BotSharp.Plugin.GoogleAi.Providers;
public static class ProviderHelper
@@ -19,12 +17,4 @@ public static class ProviderHelper
return new GenerativeAI.GoogleAi(aiSettings.Gemini.ApiKey);
}
}
-
- public static GooglePalmClient GetPalmClient(string provider, string model, IServiceProvider services)
- {
- var settingsService = services.GetRequiredService();
- var settings = settingsService.GetSetting(provider, model);
- var client = new GooglePalmClient(settings.ApiKey);
- return client;
- }
}
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/PalmTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/PalmTextCompletionProvider.cs
deleted file mode 100644
index 14d3ebab..00000000
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/PalmTextCompletionProvider.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using BotSharp.Abstraction.Hooks;
-
-namespace BotSharp.Plugin.GoogleAi.Providers.Text;
-
-[Obsolete]
-public class PalmTextCompletionProvider : ITextCompletion
-{
- private readonly IServiceProvider _services;
- private readonly ILogger _logger;
- private readonly ITokenStatistics _tokenStatistics;
-
- private string _model;
-
- public string Provider => "google-palm";
- public string Model => _model;
-
- public PalmTextCompletionProvider(
- IServiceProvider services,
- ILogger logger,
- ITokenStatistics tokenStatistics)
- {
- _services = services;
- _logger = logger;
- _tokenStatistics = tokenStatistics;
- }
-
- public async Task GetCompletion(string text, string agentId, string messageId)
- {
- var contentHooks = _services.GetHooks(agentId);
-
- // Before completion hook
- var agent = new Agent() { Id = agentId };
- var userMessage = new RoleDialogModel(AgentRole.User, text) { MessageId = messageId };
-
- foreach (var hook in contentHooks)
- {
- await hook.BeforeGenerating(agent, new List { userMessage });
- }
-
- var client = ProviderHelper.GetPalmClient(Provider, _model, _services);
- _tokenStatistics.StartTimer();
- var response = await client.GenerateTextAsync(text, null);
- _tokenStatistics.StopTimer();
-
- var message = response.Candidates.First();
- var completion = message.Output.Trim();
-
- // After completion hook
- foreach (var hook in contentHooks)
- {
- await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, completion), new TokenStatsModel
- {
- Prompt = text,
- Provider = Provider
- });
- }
-
- return completion;
- }
-
- public void SetModelName(string model)
- {
- _model = model;
- }
-}
diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/GeminiTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/TextCompletionProvider.cs
similarity index 88%
rename from src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/GeminiTextCompletionProvider.cs
rename to src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/TextCompletionProvider.cs
index abc12c3e..6a838d2f 100644
--- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/GeminiTextCompletionProvider.cs
+++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Text/TextCompletionProvider.cs
@@ -1,16 +1,13 @@
-using BotSharp.Abstraction.Agents.Enums;
-using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Hooks;
-using BotSharp.Abstraction.Loggers;
using GenerativeAI;
using GenerativeAI.Core;
namespace BotSharp.Plugin.GoogleAi.Providers.Text;
-public class GeminiTextCompletionProvider : ITextCompletion
+public class TextCompletionProvider : ITextCompletion
{
private readonly IServiceProvider _services;
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
private readonly ITokenStatistics _tokenStatistics;
private string _model;
@@ -18,10 +15,10 @@ public class GeminiTextCompletionProvider : ITextCompletion
public string Model => _model;
private GoogleAiSettings _settings;
- public GeminiTextCompletionProvider(
+ public TextCompletionProvider(
IServiceProvider services,
GoogleAiSettings googleSettings,
- ILogger logger,
+ ILogger logger,
ITokenStatistics tokenStatistics)
{
_settings = googleSettings;