diff --git a/BotSharp.sln b/BotSharp.sln index 63a3d6a0..135e7de3 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -61,6 +61,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataStorages", "DataStorage EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.MongoStorage", "src\Plugins\BotSharp.Plugin.MongoStorage\BotSharp.Plugin.MongoStorage.csproj", "{DB3DE37B-1208-4ED3-9615-A52AD0AAD69C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.GoogleAI", "src\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj", "{8BC29F8A-78D6-422C-B522-10687ADC38ED}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -213,6 +215,14 @@ Global {DB3DE37B-1208-4ED3-9615-A52AD0AAD69C}.Release|Any CPU.Build.0 = Release|Any CPU {DB3DE37B-1208-4ED3-9615-A52AD0AAD69C}.Release|x64.ActiveCfg = Release|Any CPU {DB3DE37B-1208-4ED3-9615-A52AD0AAD69C}.Release|x64.Build.0 = Release|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Debug|x64.ActiveCfg = Debug|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Debug|x64.Build.0 = Debug|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|Any CPU.Build.0 = Release|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.ActiveCfg = Release|Any CPU + {8BC29F8A-78D6-422C-B522-10687ADC38ED}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -243,6 +253,7 @@ Global {298AC787-A104-414C-B114-82BE764FBD9C} = {4F346DCE-087F-4368-AF88-EE9C720D0E69} {5CD330E1-9E5A-4112-8346-6E31CA98EF78} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C} {DB3DE37B-1208-4ED3-9615-A52AD0AAD69C} = {5CD330E1-9E5A-4112-8346-6E31CA98EF78} + {8BC29F8A-78D6-422C-B522-10687ADC38ED} = {D5293208-2BEF-42FC-A64C-5954F61720BA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs index f0bc8332..31fc95f7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ITextCompletion.cs @@ -2,5 +2,16 @@ namespace BotSharp.Abstraction.MLTasks; public interface ITextCompletion { + /// + /// The LLM provider like Microsoft Azure, OpenAI, ClaudAI + /// + string Provider { get; } + + /// + /// Set model name, one provider can consume different model or version(s) + /// + /// + void SetModelName(string model); + Task GetCompletion(string text); } diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs index 9286d85b..b381ec24 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs @@ -18,9 +18,12 @@ public partial class RoutingService }); var content = $"{prompt} Response must be in JSON format {responseFormat}"; + var state = _services.GetRequiredService(); + var provider = state.GetState("provider", _settings.Provider); + var model = state.GetState("model", _settings.Model); var chatCompletion = CompletionProvider.GetChatCompletion(_services, - provider: _settings.Provider, - model: _settings.Model); + provider: provider, + model: model); var response = chatCompletion.GetChatCompletions(_routerInstance.Router, new List { diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs index f2c7f330..ca4f11ea 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs @@ -76,7 +76,7 @@ public partial class RoutingService : IRoutingService { loopCount++; - var prompt = _settings.EnableReasoning ? "Tell me the next step?" : "Which agent is suitable to handle user's request?"; + var prompt = _settings.EnableReasoning ? "Tell me the next step?" : "Which agent is suitable to handle user's request based on the CONVERSATION?"; prompt += " Or you can handle without asking specific agent."; var inst = await GetNextInstruction(prompt); inst.Question = inst.Question ?? message; diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index 8b759166..d09abdc5 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -5,7 +5,6 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Settings; -using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.MLTasks; using BotSharp.Plugin.AzureOpenAI.Settings; using Microsoft.Extensions.DependencyInjection; @@ -25,7 +24,7 @@ public class ChatCompletionProvider : IChatCompletion private readonly ITokenStatistics _tokenStatistics; private string _model; - public virtual string Provider => "azure-openai"; + public string Provider => "azure-openai"; public ChatCompletionProvider(AzureOpenAiSettings settings, ILogger logger, diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs index 15ef859d..820bb3af 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs @@ -13,6 +13,8 @@ public class TextCompletionProvider : ITextCompletion private readonly AzureOpenAiSettings _settings; private readonly ILogger _logger; bool _useAzureOpenAI = true; + private string _model; + public string Provider => "azure-openai"; public TextCompletionProvider(AzureOpenAiSettings settings, ILogger logger) { @@ -49,6 +51,11 @@ public class TextCompletionProvider : ITextCompletion return completion.Trim(); } + public void SetModelName(string model) + { + _model = model; + } + private OpenAIClient GetOpenAIClient() { OpenAIClient client = _useAzureOpenAI diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj b/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj new file mode 100644 index 00000000..44e87f6c --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.1 + enable + $(LangVersion) + $(BotSharpVersion) + $(GeneratePackageOnBuild) + + + + + + + + + + + diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs new file mode 100644 index 00000000..ebf01107 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/GoogleAiPlugin.cs @@ -0,0 +1,22 @@ +using BotSharp.Abstraction.Plugins; +using BotSharp.Plugin.GoogleAI.Providers; +using BotSharp.Plugin.GoogleAI.Settings; + +namespace BotSharp.Plugin.GoogleAI; + +public class GoogleAiPlugin : IBotSharpPlugin +{ + public void RegisterDI(IServiceCollection services, IConfiguration config) + { + var settings = new GoogleAiSettings(); + config.Bind("GoogleAi", settings); + services.AddSingleton(x => + { + Console.WriteLine($"Loaded Google AI settings: {settings.PaLM.Endpoint} {settings.PaLM.ApiKey.SubstringMax(4)}"); + return settings; + }); + + services.AddScoped(); + services.AddScoped(); + } +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs new file mode 100644 index 00000000..9e9dbd8b --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs @@ -0,0 +1,63 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Conversations; +using BotSharp.Plugin.GoogleAI.Settings; +using LLMSharp.Google.Palm; +using Microsoft.Extensions.Logging; + +namespace BotSharp.Plugin.GoogleAI.Providers; + +public class ChatCompletionProvider : IChatCompletion +{ + public string Provider => "google-ai"; + private readonly IServiceProvider _services; + private readonly GoogleAiSettings _settings; + private readonly ILogger _logger; + private readonly ITokenStatistics _tokenStatistics; + private string _model; + + public ChatCompletionProvider(IServiceProvider services, + GoogleAiSettings settings, + ILogger logger, + ITokenStatistics tokenStatistics) + { + _services = services; + _settings = settings; + _logger = logger; + _tokenStatistics = tokenStatistics; + } + + public RoleDialogModel GetChatCompletions(Agent agent, List conversations) + { + var client = new GooglePalmClient(apiKey: _settings.PaLM.ApiKey); + List messages = new() + { + new(conversations.Last().Content, "user"), + }; + _tokenStatistics.StartTimer(); + var response = client.ChatAsync(messages, agent.Instruction, null).Result; + _tokenStatistics.StopTimer(); + + var message = response.Candidates.First(); + var msg = new RoleDialogModel(AgentRole.Assistant, message.Content) + { + CurrentAgentId = agent.Id + }; + + return msg; + } + + public Task GetChatCompletionsAsync(Agent agent, List conversations, Func onMessageReceived, Func onFunctionExecuting) + { + throw new NotImplementedException(); + } + + public Task GetChatCompletionsStreamingAsync(Agent agent, List conversations, Func onMessageReceived) + { + throw new NotImplementedException(); + } + + public void SetModelName(string model) + { + _model = model; + } +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs new file mode 100644 index 00000000..8063d5d5 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs @@ -0,0 +1,17 @@ +namespace BotSharp.Plugin.GoogleAI.Providers; + +public class TextCompletionProvider : ITextCompletion +{ + public string Provider => "google-ai"; + private string _model; + + public Task GetCompletion(string text) + { + throw new NotImplementedException(); + } + + public void SetModelName(string model) + { + _model = model; + } +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Settings/GoogleAiSettings.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Settings/GoogleAiSettings.cs new file mode 100644 index 00000000..d515b23f --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Settings/GoogleAiSettings.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Plugin.GoogleAI.Settings; + +public class GoogleAiSettings +{ + public PaLMSetting PaLM { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Settings/PaLMSetting.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Settings/PaLMSetting.cs new file mode 100644 index 00000000..29894614 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Settings/PaLMSetting.cs @@ -0,0 +1,7 @@ +namespace BotSharp.Plugin.GoogleAI.Settings; + +public class PaLMSetting +{ + public string Endpoint { get; set; } = string.Empty; + public string ApiKey { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs new file mode 100644 index 00000000..8cb9a723 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs @@ -0,0 +1,13 @@ +global using System; +global using System.Collections.Generic; +global using System.Text; +global using System.Threading.Tasks; +global using System.Linq; +global using System.Text.Json; +global using BotSharp.Abstraction.Conversations.Models; +global using BotSharp.Abstraction.Agents.Models; +global using BotSharp.Abstraction.MLTasks; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; +global using System.Text.Json.Serialization; +global using BotSharp.Abstraction.Utilities; \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemVectorDatabase.cs b/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemVectorDatabase.cs index 38104726..40adcf9d 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemVectorDatabase.cs +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/MemVecDb/MemVectorDatabase.cs @@ -85,6 +85,7 @@ public class MemVectorDatabase : IVectorDb { var simiMatix = CalCosineSimilarity(vec, records); + topK = Math.Min(topK, records.Count); var topIndex = np.argsort(simiMatix)["::-1"][$":{topK}"]; var resIndex = new List(); diff --git a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs index aa42b7e2..f33b3bca 100644 --- a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs @@ -14,6 +14,8 @@ public class TextCompletionProvider : ITextCompletion { private readonly IServiceProvider _services; private readonly LlamaSharpSettings _settings; + private string _model; + public string Provider => "llama-sharp"; public TextCompletionProvider(IServiceProvider services, LlamaSharpSettings settings) @@ -42,4 +44,9 @@ public class TextCompletionProvider : ITextCompletion return Task.FromResult(totalResponse); } + + public void SetModelName(string model) + { + _model = model; + } } diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index 71314ac1..ba130a66 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -29,17 +29,13 @@ - - - - @@ -52,6 +48,7 @@ + diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index fe4552c6..1ee508f7 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -50,6 +50,13 @@ } }, + "GoogleAi": { + "PaLM": { + "Endpoint": "https://generativelanguage.googleapis.com", + "ApiKey": "" + } + }, + "HuggingFace": { "Endpoint": "https://api-inference.huggingface.co", "Model": "tiiuae/falcon-180B-chat", @@ -113,6 +120,7 @@ "BotSharp.Core", "BotSharp.Plugin.MongoStorage", "BotSharp.Plugin.AzureOpenAI", + "BotSharp.Plugin.GoogleAI", "BotSharp.Plugin.MetaAI", "BotSharp.Plugin.HuggingFace", "BotSharp.Plugin.LLamaSharp",