From 538753571a653c2ae68ed57778918f43fdadbb24 Mon Sep 17 00:00:00 2001 From: Haiping Chen <101423@smsassist.com> Date: Wed, 13 Dec 2023 12:12:25 -0600 Subject: [PATCH 1/4] Unify the LLM Provider Settings #234 --- docs/agent/intro.md | 19 +++++--- docs/conf.py | 4 +- docs/quick-start/installation.md | 31 +++++++++---- docs/quick-start/overview.md | 13 +----- .../Agents/Models/Agent.cs | 5 ++ .../Agents/Models/AgentLlmConfig.cs | 16 +++++++ .../Conversations/Models/TokenStatsModel.cs | 12 +---- .../Evaluations/Settings/EvaluatorSetting.cs | 4 +- .../MLTasks/ILlmProviderSettingService.cs | 8 ++++ .../MLTasks/Settings/ChatCompletionSetting.cs | 7 --- .../MLTasks/Settings/LlmModelSetting.cs | 30 ++++++++++++ .../MLTasks/Settings/LlmProviderSetting.cs | 15 ++++++ .../MLTasks/Settings/TextCompletionSetting.cs | 7 --- .../Routing/Models/RoutingContext.cs | 4 +- .../Routing/Settings/RoutingSettings.cs | 5 +- .../BotSharp.Core/BotSharpCoreExtensions.cs | 21 +++++---- .../ConversationService.SendMessage.cs | 2 +- .../Conversations/Services/TokenStatistics.cs | 22 +++++---- .../Evaluations/EvaluatingService.cs | 2 +- .../Infrastructures/CompletionProvider.cs | 11 ++--- .../LlmProviderSettingService.cs | 36 +++++++++++++++ .../BotSharp.Core/Planning/HFPlanner.cs | 5 +- .../BotSharp.Core/Planning/NaivePlanner.cs | 5 +- .../Routing/Hooks/RoutingAgentHook.cs | 2 +- .../Routing/RoutingService.InvokeAgent.cs | 4 +- .../BotSharp.Core/Routing/RoutingService.cs | 2 +- .../Hooks/TokenStatsConversationHook.cs | 2 - .../Conversations/NewMessageModel.cs | 3 -- .../AzureOpenAiPlugin.cs | 2 +- .../Providers/ChatCompletionProvider.cs | 8 ++-- .../Providers/ProviderHelper.cs | 19 +++----- .../Providers/TextCompletionProvider.cs | 3 +- .../Settings/AzureOpenAiSettings.cs | 4 +- .../Settings/GPT4Settings.cs | 8 ---- .../RoutingConversationHook.cs | 2 +- .../Services/TwilioService.cs | 4 +- src/WebStarter/appsettings.json | 46 +++++++++++-------- .../agent.json | 6 ++- .../agent.json | 5 +- 39 files changed, 251 insertions(+), 153 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderSettingService.cs delete mode 100644 src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/ChatCompletionSetting.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmModelSetting.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs delete mode 100644 src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/TextCompletionSetting.cs create mode 100644 src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderSettingService.cs delete mode 100644 src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/GPT4Settings.cs diff --git a/docs/agent/intro.md b/docs/agent/intro.md index ededa11ce..e832d5372 100644 --- a/docs/agent/intro.md +++ b/docs/agent/intro.md @@ -16,14 +16,19 @@ Suppose we need to write a Pizza restaurant order AI Bot. First, specify a name BotSharp uses the latest large language model in natural language understanding, can interact with OpenAI's ChatGPT, and also supports the most widely used open source large language model [LLaMA](https://ai.meta.com/blog/large-language-model-llama-meta-ai/) and its fine-tuning model. In this example, we use [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service) as the LLM engine. ```json -"AzureOpenAi": { - "ApiKey": "", - "Endpoint": "", - "DeploymentModel": { - "ChatCompletionModel": "", - "TextCompletionModel": "" +"LlmProviders": [ + { + "Provider": "azure-openai", + "Models": [{ + "Name": "gpt-35-turbo", + "ApiKey": "", + "Endpoint": "https://gpt-35-turbo.openai.azure.com/", + "Type": "chat", + "PromptCost": 0.0015, + "CompletionCost": 0.002 + }] } -} +] ``` If you use the installation package to run, please ensure that the [BotSharp.Plugin.AzureOpenAI](https://www.nuget.org/packages/BotSharp.Plugin.AzureOpenAI) plugin package is installed. diff --git a/docs/conf.py b/docs/conf.py index 0aacd9964..a69f2133f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,9 +64,9 @@ # built documents. # # The short X.Y version. -version = '0.20' +version = '0.21' # The full version, including alpha/beta/rc tags. -release = '0.20.0' +release = '0.21.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/quick-start/installation.md b/docs/quick-start/installation.md index 4f670dbed..319bdf64c 100644 --- a/docs/quick-start/installation.md +++ b/docs/quick-start/installation.md @@ -19,14 +19,29 @@ PS D:\> dotnet build `BotSharp` can work with serveral LLM providers. Update `appsettings.json` in your project. Below config is tasking Azure OpenAI as the LLM backend ```json -"AzureOpenAi": { - "ApiKey": "", - "Endpoint": "https://xxx.openai.azure.com/", - "DeploymentModel": { - "ChatCompletionModel": "", - "TextCompletionModel": "" - } -} +"LlmProviders": [ + { + "Provider": "azure-openai", + "Models": [ + { + "Name": "gpt-35-turbo", + "ApiKey": "", + "Endpoint": "https://gpt-35-turbo.openai.azure.com/", + "Type": "chat", + "PromptCost": 0.0015, + "CompletionCost": 0.002 + }, + { + "Name": "gpt-35-turbo-instruct", + "ApiKey": "", + "Endpoint": "https://gpt-35-turbo-instruct.openai.azure.com/", + "Type": "text", + "PromptCost": 0.0015, + "CompletionCost": 0.002 + } + ] + } +] ``` ### Run backend web project diff --git a/docs/quick-start/overview.md b/docs/quick-start/overview.md index 12146ba3e..82ddce158 100644 --- a/docs/quick-start/overview.md +++ b/docs/quick-start/overview.md @@ -21,15 +21,4 @@ Even with this simple question, you can see conversational experience are hard t Your code would have to handle all these different types of requests ro carry out the same logic: looking up some forecast information for a feature. For this reason, a traditional computer interface would tend to force users to input a well-known, standard request at the detriment of the user experience, because it's just easier. -However, BotSharp lets you easily achieve a conversational user experience by handling the natural language understanding (NLU) for you. When you use BotSharp, you can create agents that can understand the meaning of natural language and the nuances and trainslate that to structured meaning your software can understand. - -Features -------------- - -* Built-in multi-Agents management, easy to build Bot as a Service platform. -* Integrate with multiple LLMs like ChatGPT and LLaMA. -* Using plug-in design, it is easy to expand functions. -* Working with multiple Vector Stores for senmatic search. -* Supporting different UI providers like [Chatbot UI](https://github.com/SciSharp/chatbot-ui) and [HuggingChat UI](https://github.com/huggingface/chat-ui). -* Integrated with popular social platforms like Facebook Messenger, Slack and Telegram. -* Providing REST APIs to work with your own UI. \ No newline at end of file +However, BotSharp lets you easily achieve a conversational user experience by handling the natural language understanding (NLU) for you. When you use BotSharp, you can create agents that can understand the meaning of natural language and the nuances and trainslate that to structured meaning your software can understand. \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 4092f9c79..3e127125c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -11,6 +11,11 @@ public class Agent public DateTime CreatedDateTime { get; set; } public DateTime UpdatedDateTime { get; set; } + /// + /// Default LLM settings + /// + public AgentLlmConfig? LlmConfig { get; set; } + /// /// Instruction /// diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs new file mode 100644 index 000000000..5b075f35d --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -0,0 +1,16 @@ +namespace BotSharp.Abstraction.Agents.Models; + +public class AgentLlmConfig +{ + /// + /// Completion Provider + /// + [JsonPropertyName("provider")] + public string? Provider { get; set; } + + /// + /// Model name + /// + [JsonPropertyName("model")] + public string? Model { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/TokenStatsModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/TokenStatsModel.cs index cd54eb048..233888074 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/TokenStatsModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/TokenStatsModel.cs @@ -2,18 +2,10 @@ namespace BotSharp.Abstraction.Conversations.Models; public class TokenStatsModel { + public string Provider { get; set; } public string Model { get; set; } public string Prompt { get; set; } public int PromptCount { get; set; } public int CompletionCount { get; set; } - - /// - /// Prompt cost per 1K token - /// - public float PromptCost { get; set; } - - /// - /// Completion cost per 1K token - /// - public float CompletionCost { get; set; } + public AgentLlmConfig LlmConfig { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs b/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs index c08f4f71e..5bb3f8501 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs @@ -2,7 +2,5 @@ namespace BotSharp.Abstraction.Evaluations.Settings; public class EvaluatorSetting { - public string EvaluatorId { get; set; } - public string Provider { get; set; } - public string Model { get; set; } + public string AgentId { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderSettingService.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderSettingService.cs new file mode 100644 index 000000000..bfe5d4204 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderSettingService.cs @@ -0,0 +1,8 @@ +using BotSharp.Abstraction.MLTasks.Settings; + +namespace BotSharp.Abstraction.MLTasks; + +public interface ILlmProviderSettingService +{ + LlmModelSetting GetSetting(string provider, string model); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/ChatCompletionSetting.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/ChatCompletionSetting.cs deleted file mode 100644 index ba0a6a59b..000000000 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/ChatCompletionSetting.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BotSharp.Abstraction.MLTasks.Settings; - -public class ChatCompletionSetting -{ - public string Provider { get; set; } - public string Model { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmModelSetting.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmModelSetting.cs new file mode 100644 index 000000000..07fbe63b7 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmModelSetting.cs @@ -0,0 +1,30 @@ +namespace BotSharp.Abstraction.MLTasks.Settings; + +public class LlmModelSetting +{ + public string Name { get; set; } + public string ApiKey { get; set; } + public string Endpoint { get; set; } + public LlmModelType Type { get; set; } = LlmModelType.Chat; + + /// + /// Prompt cost per 1K token + /// + public float PromptCost { get; set; } + + /// + /// Completion cost per 1K token + /// + public float CompletionCost { get; set; } + + public override string ToString() + { + return $"[{Type}] {Name} {Endpoint}"; + } +} + +public enum LlmModelType +{ + Text = 1, + Chat = 2 +} diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs new file mode 100644 index 000000000..b3a9d28e2 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs @@ -0,0 +1,15 @@ +namespace BotSharp.Abstraction.MLTasks.Settings; + +public class LlmProviderSetting +{ + public string Provider { get; set; } + = "azure-openai"; + + public List Models { get; set; } + = new List(); + + public override string ToString() + { + return $"{Provider} with {Models.Count} models"; + } +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/TextCompletionSetting.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/TextCompletionSetting.cs deleted file mode 100644 index 7fbb1a7d2..000000000 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/TextCompletionSetting.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BotSharp.Abstraction.MLTasks.Settings; - -public class TextCompletionSetting -{ - public string Provider { get; set; } - public string Model { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs index c65ea62f5..18a20713e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs @@ -22,14 +22,14 @@ public RoutingContext(RoutingSettings setting) /// Agent that can handl user original goal. /// public string OriginAgentId - => _stack.Where(x => x != _setting.RouterId).Last(); + => _stack.Where(x => x != _setting.AgentId).Last(); public bool IsEmpty => !_stack.Any(); public string GetCurrentAgentId() { if (_stack.Count == 0) { - _stack.Push(_setting.RouterId); + _stack.Push(_setting.AgentId); } return _stack.Peek(); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs index 62a6ae4ac..8428ac999 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs @@ -5,10 +5,7 @@ public class RoutingSettings /// /// Router Agent Id /// - public string RouterId { get; set; } = string.Empty; + public string AgentId { get; set; } = string.Empty; public string Planner { get; set; } = string.Empty; - public string Provider { get; set; } = string.Empty; - - public string Model { get; set; } = string.Empty; } diff --git a/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs index afa93e334..bfb8dca16 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs @@ -19,6 +19,8 @@ using BotSharp.Abstraction.MLTasks.Settings; using BotSharp.Abstraction.Planning; using BotSharp.Core.Planning; +using BotSharp.Abstraction.MLTasks; +using static Dapper.SqlMapper; namespace BotSharp.Core; @@ -27,7 +29,7 @@ public static class BotSharpCoreExtensions public static IServiceCollection AddBotSharpCore(this IServiceCollection services, IConfiguration config) { services.AddScoped(); - + services.AddScoped(); services.AddScoped(); var agentSettings = new AgentSettings(); @@ -51,13 +53,16 @@ public static IServiceCollection AddBotSharpCore(this IServiceCollection service config.Bind("Database", myDatabaseSettings); services.AddSingleton((IServiceProvider x) => myDatabaseSettings); - var textCompletionSettings = new TextCompletionSetting(); - config.Bind("TextCompletion", textCompletionSettings); - services.AddSingleton((IServiceProvider x) => textCompletionSettings); - - var chatCompletionSettings = new ChatCompletionSetting(); - config.Bind("ChatCompletion", chatCompletionSettings); - services.AddSingleton((IServiceProvider x) => chatCompletionSettings); + var llmProviders = new List(); + config.Bind("LlmProviders", llmProviders); + services.AddSingleton((IServiceProvider x) => + { + foreach (var llmProvider in llmProviders) + { + Console.WriteLine($"Loaded LlmProvider {llmProvider.Provider} settings with {llmProvider.Models.Count} models."); + } + return llmProviders; + }); RegisterPlugins(services, config); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs index ad1faeef0..eebf4c006 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs @@ -59,7 +59,7 @@ public async Task SendMessage(string agentId, var routing = _services.GetRequiredService(); var settings = _services.GetRequiredService(); - response = agentId == settings.RouterId ? + response = agentId == settings.AgentId ? await routing.InstructLoop(message) : await routing.ExecuteDirectly(agent, message); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs index ef5d2ba36..62b52f53c 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.MLTasks; using System.Diagnostics; using System.Drawing; @@ -36,19 +37,24 @@ public void AddToken(TokenStatsModel stats) _model = stats.Model; _promptTokenCount += stats.PromptCount; _completionTokenCount += stats.CompletionCount; - _promptCost += stats.PromptCount / 1000f * stats.PromptCost; - _completionCost += stats.CompletionCount / 1000f * stats.CompletionCost; + + var settingsService = _services.GetRequiredService(); + var settings = settingsService.GetSetting(stats.Provider, _model); + + _promptCost += stats.PromptCount / 1000f * settings.PromptCost; + _completionCost += stats.CompletionCount / 1000f * settings.CompletionCost; // Accumulated Token var stat = _services.GetRequiredService(); - var count1 = int.Parse(stat.GetState("prompt_total", "0")); - stat.SetState("prompt_total", stats.PromptCount + count1); - var count2 = int.Parse(stat.GetState("completion_total", "0")); - stat.SetState("completion_total", stats.CompletionCount + count2); + var inputCount = int.Parse(stat.GetState("prompt_total", "0")); + stat.SetState("prompt_total", stats.PromptCount + inputCount); + var outputCount = int.Parse(stat.GetState("completion_total", "0")); + stat.SetState("completion_total", stats.CompletionCount + outputCount); // Total cost - var count3 = float.Parse(stat.GetState("llm_total_cost", "0")); - stat.SetState("llm_total_cost", stats.PromptCount / 1000f * stats.PromptCost + stats.CompletionCount / 1000f * stats.CompletionCost + count3); + var total_cost = float.Parse(stat.GetState("llm_total_cost", "0")); + total_cost += Cost; + stat.SetState("llm_total_cost", total_cost); } public void PrintStatistics() diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs index 75191edfa..340b8f7e3 100644 --- a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs +++ b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs @@ -20,7 +20,7 @@ public EvaluatingService(IServiceProvider services, EvaluatorSetting settings) public async Task Execute(string task, EvaluationRequest request) { var agentService = _services.GetRequiredService(); - var evaluator = await agentService.GetAgent(_settings.EvaluatorId); + var evaluator = await agentService.GetAgent(_settings.AgentId); // Task execution mode evaluator.Instruction = evaluator.Templates.First(x => x.Name == "instruction.executor").Content; var taskPrompt = evaluator.Templates.First(x => x.Name == $"task.{task}").Content; diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs index 48d063d04..4dac7e689 100644 --- a/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs +++ b/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.MLTasks; -using BotSharp.Abstraction.MLTasks.Settings; namespace BotSharp.Core.Infrastructures; @@ -7,19 +6,18 @@ public class CompletionProvider { public static IChatCompletion GetChatCompletion(IServiceProvider services, string? provider = null, string? model = null) { - var settings = services.GetRequiredService(); var completions = services.GetServices(); var state = services.GetRequiredService(); if (string.IsNullOrEmpty(provider)) { - provider = state.GetState("provider", settings.Provider ?? "azure-openai"); + provider = state.GetState("provider", "azure-openai"); } if (string.IsNullOrEmpty(model)) { - model = state.GetState("model", settings.Model ?? "gpt-3.5-turbo"); + model = state.GetState("model", "gpt-35-turbo-4k"); } var completer = completions.FirstOrDefault(x => x.Provider == provider); @@ -36,19 +34,18 @@ public static IChatCompletion GetChatCompletion(IServiceProvider services, strin public static ITextCompletion GetTextCompletion(IServiceProvider services, string? provider = null, string? model = null) { - var settings = services.GetRequiredService(); var completions = services.GetServices(); var state = services.GetRequiredService(); if (string.IsNullOrEmpty(provider)) { - provider = state.GetState("provider", settings.Provider ?? "azure-openai"); + provider = state.GetState("provider", "azure-openai"); } if (string.IsNullOrEmpty(model)) { - model = state.GetState("model", settings.Model ?? "gpt-3.5-turbo"); + model = state.GetState("model", "gpt-35-turbo-instruct"); } var completer = completions.FirstOrDefault(x => x.Provider == provider); diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderSettingService.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderSettingService.cs new file mode 100644 index 000000000..a3f8a8d35 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderSettingService.cs @@ -0,0 +1,36 @@ +using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.MLTasks.Settings; + +namespace BotSharp.Core.Infrastructures; + +public class LlmProviderSettingService : ILlmProviderSettingService +{ + private readonly IServiceProvider _services; + private readonly ILogger _logger; + + public LlmProviderSettingService(IServiceProvider services, ILogger logger) + { + _services = services; + _logger = logger; + } + + public LlmModelSetting? GetSetting(string provider, string model) + { + var settings = _services.GetRequiredService>(); + var providerSetting = settings.FirstOrDefault(p => p.Provider.Equals(provider, StringComparison.CurrentCultureIgnoreCase)); + if (providerSetting == null) + { + _logger.LogError($"Can't find provider settings for {provider}"); + return null; + } + + var modelSetting = providerSetting.Models.FirstOrDefault(m => m.Name.Equals(model, StringComparison.CurrentCultureIgnoreCase)); + if (modelSetting == null) + { + _logger.LogError($"Can't find model settings for {provider}.{model}"); + return null; + } + + return modelSetting; + } +} diff --git a/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs index c5c2f13dd..5a109452a 100644 --- a/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs +++ b/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs @@ -30,10 +30,9 @@ public async Task GetNextInstruction(Agent router, string m RoleDialogModel response = default; var inst = new FunctionCallFromLlm(); - var routerSetting = _services.GetRequiredService(); var completion = CompletionProvider.GetChatCompletion(_services, - provider: routerSetting.Provider, - model: routerSetting.Model); + provider: router?.LlmConfig?.Provider, + model: router?.LlmConfig?.Model); int retryCount = 0; while (retryCount < 3) diff --git a/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs index f69d31aec..a2de09922 100644 --- a/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs +++ b/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs @@ -32,10 +32,9 @@ public async Task GetNextInstruction(Agent router, string m var completion = CompletionProvider.GetTextCompletion(_services);*/ // chat completion - var routerSetting = _services.GetRequiredService(); var completion = CompletionProvider.GetChatCompletion(_services, - provider: routerSetting.Provider, - model: routerSetting.Model); + provider: router?.LlmConfig?.Provider, + model: router?.LlmConfig?.Model); int retryCount = 0; while (retryCount < 3) diff --git a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs index 07647e10f..2d3d3ab23 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs @@ -7,7 +7,7 @@ namespace BotSharp.Core.Routing.Hooks; public class RoutingAgentHook : AgentHookBase { private readonly RoutingSettings _routingSetting; - public override string SelfId => _routingSetting.RouterId; + public override string SelfId => _routingSetting.AgentId; public RoutingAgentHook(IServiceProvider services, AgentSettings settings, RoutingSettings routingSetting) : base(services, settings) diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index 566993728..e218e9b71 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -21,7 +21,9 @@ public async Task InvokeAgent(string agentId, List dialog var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(agentId); - var chatCompletion = CompletionProvider.GetChatCompletion(_services); + var chatCompletion = CompletionProvider.GetChatCompletion(_services, + provider: agent?.LlmConfig?.Provider, + model: agent.LlmConfig?.Model); var message = dialogs.Last(); var response = chatCompletion.GetChatCompletions(agent, dialogs); diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs index a92e4a6e1..8304b46ef 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs @@ -64,7 +64,7 @@ public async Task ExecuteDirectly(Agent agent, RoleDialogModel public async Task InstructLoop(RoleDialogModel message) { var agentService = _services.GetRequiredService(); - _router = await agentService.LoadAgent(_settings.RouterId); + _router = await agentService.LoadAgent(_settings.AgentId); RoleDialogModel response = default; diff --git a/src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs b/src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs index c7e05d151..f9bfb6e5b 100644 --- a/src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs +++ b/src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs @@ -18,8 +18,6 @@ public async Task BeforeGenerating(Agent agent, List conversati public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats) { _tokenStatistics.StopTimer(); - tokenStats.PromptCost = 0.0015f; - tokenStats.CompletionCost = 0.002f; _tokenStatistics.AddToken(tokenStats); await Task.CompletedTask; } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs index 1750a3037..939fa601a 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs @@ -1,6 +1,3 @@ -using BotSharp.Abstraction.Conversations.Enums; -using BotSharp.Abstraction.Conversations.Models; - namespace BotSharp.OpenAPI.ViewModels.Conversations; public class NewMessageModel : IncomingMessageModel diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs index 09c9d32ea..624ecfe5a 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs @@ -23,7 +23,7 @@ public void RegisterDI(IServiceCollection services, IConfiguration config) config.Bind("AzureOpenAi", settings); services.AddSingleton(x => { - Console.WriteLine($"Loaded AzureOpenAi settings: ({settings.Endpoint}) {settings.ApiKey.SubstringMax(4)}"); + Console.WriteLine($"Loaded AzureOpenAi settings"); return settings; }); diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index d2bd08a18..3953756a0 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -45,7 +45,7 @@ public RoleDialogModel GetChatCompletions(Agent agent, List con hook.BeforeGenerating(agent, conversations).Wait(); } - var client = ProviderHelper.GetClient(_model, _settings); + var client = ProviderHelper.GetClient(_model, _services); var (prompt, chatCompletionsOptions) = PrepareOptions(agent, conversations); chatCompletionsOptions.DeploymentName = _model; var response = client.GetChatCompletions(chatCompletionsOptions); @@ -81,6 +81,7 @@ public RoleDialogModel GetChatCompletions(Agent agent, List con hook.AfterGenerated(responseMessage, new TokenStatsModel { Prompt = prompt, + Provider = Provider, Model = _model, PromptCount = response.Value.Usage.PromptTokens, CompletionCount = response.Value.Usage.CompletionTokens @@ -103,7 +104,7 @@ public async Task GetChatCompletionsAsync(Agent agent, await hook.BeforeGenerating(agent, conversations); } - var client = ProviderHelper.GetClient(_model, _settings); + var client = ProviderHelper.GetClient(_model, _services); var (prompt, chatCompletionsOptions) = PrepareOptions(agent, conversations); chatCompletionsOptions.DeploymentName = _model; @@ -122,6 +123,7 @@ public async Task GetChatCompletionsAsync(Agent agent, await hook.AfterGenerated(msg, new TokenStatsModel { Prompt = prompt, + Provider = Provider, Model = _model, PromptCount = response.Value.Usage.PromptTokens, CompletionCount = response.Value.Usage.CompletionTokens @@ -159,7 +161,7 @@ public async Task GetChatCompletionsAsync(Agent agent, public async Task GetChatCompletionsStreamingAsync(Agent agent, List conversations, Func onMessageReceived) { - var client = ProviderHelper.GetClient(_model, _settings); + var client = ProviderHelper.GetClient(_model, _services); var (prompt, chatCompletionsOptions) = PrepareOptions(agent, conversations); chatCompletionsOptions.DeploymentName = _model; var response = await client.GetChatCompletionsStreamingAsync(chatCompletionsOptions); diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ProviderHelper.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ProviderHelper.cs index 2be17f0aa..a88459f03 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ProviderHelper.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ProviderHelper.cs @@ -1,26 +1,21 @@ using Azure.AI.OpenAI; using Azure; using System; -using BotSharp.Plugin.AzureOpenAI.Settings; using BotSharp.Abstraction.Conversations.Models; using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using BotSharp.Abstraction.MLTasks; namespace BotSharp.Plugin.AzureOpenAI.Providers; public class ProviderHelper { - public static OpenAIClient GetClient(string model, AzureOpenAiSettings settings) + public static OpenAIClient GetClient(string model, IServiceProvider services) { - if (model.Contains("gpt-4") || model.Contains("gpt4")) - { - var client = new OpenAIClient(new Uri(settings.GPT4.Endpoint), new AzureKeyCredential(settings.GPT4.ApiKey)); - return client; - } - else - { - var client = new OpenAIClient(new Uri(settings.Endpoint), new AzureKeyCredential(settings.ApiKey)); - return client; - } + var settingsService = services.GetRequiredService(); + var settings = settingsService.GetSetting("azure-openai", model); + var client = new OpenAIClient(new Uri(settings.Endpoint), new AzureKeyCredential(settings.ApiKey)); + return client; } public static List GetChatSamples(List lines) diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs index c24d20ef7..1078a36b5 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs @@ -50,7 +50,7 @@ public async Task GetCompletion(string text, string agentId, string mess message })).ToArray()); - var client = ProviderHelper.GetClient(_model, _settings); + var client = ProviderHelper.GetClient(_model, _services); var completionsOptions = new CompletionsOptions() { @@ -87,6 +87,7 @@ public async Task GetCompletion(string text, string agentId, string mess hook.AfterGenerated(responseMessage, new TokenStatsModel { Prompt = text, + Provider = Provider, Model = _model, PromptCount = response.Value.Usage.PromptTokens, CompletionCount = response.Value.Usage.CompletionTokens diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/AzureOpenAiSettings.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/AzureOpenAiSettings.cs index 60858a8f0..d64482ffc 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/AzureOpenAiSettings.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/AzureOpenAiSettings.cs @@ -2,7 +2,5 @@ namespace BotSharp.Plugin.AzureOpenAI.Settings; public class AzureOpenAiSettings { - public string ApiKey { get; set; } = string.Empty; - public string Endpoint { get; set; } = string.Empty; - public GPT4Settings GPT4 { get; set; } + } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/GPT4Settings.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/GPT4Settings.cs deleted file mode 100644 index eab41763a..000000000 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Settings/GPT4Settings.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace BotSharp.Plugin.AzureOpenAI.Settings; - -public class GPT4Settings -{ - public string ApiKey { get; set; } - public string Endpoint { get; set; } - public string DeploymentModel { get; set; } -} diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs index 368f49bfa..11744d0d5 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs @@ -53,7 +53,7 @@ public override async Task OnMessageReceived(RoleDialogModel message) public override async Task OnResponseGenerated(RoleDialogModel message) { var routerSettings = _services.GetRequiredService(); - bool saveFlag = message.CurrentAgentId != routerSettings.RouterId; + bool saveFlag = message.CurrentAgentId != routerSettings.AgentId; if (saveFlag) { diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs index dcbcf30c0..374a00ad0 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs @@ -56,7 +56,7 @@ public VoiceResponse ReturnInstructions(string message) { Gather.InputEnum.Speech }, - Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}") + Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.AgentId}") }; gather.Say(message); response.Append(gather); @@ -82,7 +82,7 @@ public VoiceResponse HoldOn(int interval, string message = null) var gather = new Gather() { Input = new List() { Gather.InputEnum.Speech }, - Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}"), + Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.AgentId}"), ActionOnEmptyResult = true }; if (!string.IsNullOrEmpty(message)) diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 6dbcbc2c2..1558291ad 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -13,17 +13,37 @@ "Key": "31ba6052aa6f4569901facc3a41fcb4a" }, + "LlmProviders": [ + { + "Provider": "azure-openai", + "Models": [ + { + "Name": "gpt-35-turbo", + "ApiKey": "", + "Endpoint": "https://gpt-35-turbo.openai.azure.com/", + "Type": "chat", + "PromptCost": 0.0015, + "CompletionCost": 0.002 + }, + { + "Name": "gpt-35-turbo-instruct", + "ApiKey": "", + "Endpoint": "https://gpt-35-turbo-instruct.openai.azure.com/", + "Type": "text", + "PromptCost": 0.0015, + "CompletionCost": 0.002 + } + ] + } + ], + "Router": { - "RouterId": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a", - "Planner": "NaivePlanner", - "Provider": "azure-openai", - "Model": "gpt-3.5-turbo" + "AgentId": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a", + "Planner": "NaivePlanner" }, "Evaluator": { - "EvaluatorId": "dfd9b46d-d00c-40af-8a75-3fbdc2b89869", - "Provider": "azure-openai", - "Model": "gpt-3.5-turbo" + "AgentId": "dfd9b46d-d00c-40af-8a75-3fbdc2b89869" }, "Agent": { @@ -47,19 +67,7 @@ "NumberOfGpuLayer": 10 }, - "ChatCompletion": { - "Provider": "azure-openai", - "Model": "gpt-3.5-turbo" - }, - - "TextCompletion": { - "Provider": "azure-openai", - "Model": "gpt-3.5-turbo" - }, - "AzureOpenAi": { - "ApiKey": "", - "Endpoint": "" }, "GoogleAi": { diff --git a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json index af5d7e1a9..24cb1d763 100644 --- a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json +++ b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json @@ -4,5 +4,9 @@ "createdDateTime": "2023-08-18T14:39:32.2349685Z", "updatedDateTime": "2023-08-18T14:39:32.2349686Z", "id": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a", - "isPublic": true + "isPublic": true, + "llmConfig": { + "provider": "azure-openai", + "model": "gpt-35-turbo" + } } \ No newline at end of file diff --git a/src/WebStarter/data/agents/dfd9b46d-d00c-40af-8a75-3fbdc2b89869/agent.json b/src/WebStarter/data/agents/dfd9b46d-d00c-40af-8a75-3fbdc2b89869/agent.json index 7b6500a58..26f159728 100644 --- a/src/WebStarter/data/agents/dfd9b46d-d00c-40af-8a75-3fbdc2b89869/agent.json +++ b/src/WebStarter/data/agents/dfd9b46d-d00c-40af-8a75-3fbdc2b89869/agent.json @@ -3,5 +3,8 @@ "description": "Evaluate the performance of the LLM agents", "createdDateTime": "2023-08-18T00:00:00Z", "updatedDateTime": "2023-08-18T00:00:00Z", - "id": "dfd9b46d-d00c-40af-8a75-3fbdc2b89869" + "id": "dfd9b46d-d00c-40af-8a75-3fbdc2b89869", + "llmConfig": { + "model": "gpt-35-turbo-instruct" + } } \ No newline at end of file From 92ff9e6f3c8f9c194917050bf4fa890b4342e03f Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 13 Dec 2023 14:26:46 -0600 Subject: [PATCH 2/4] add agent llm config --- .../Agents/Enums/AgentField.cs | 3 +- .../Agents/Models/Agent.cs | 12 +++++++ .../Agents/Models/AgentLlmConfig.cs | 9 ++++++ .../Evaluations/Settings/EvaluatorSetting.cs | 2 +- .../Routing/Models/RoutingContext.cs | 4 +-- .../Routing/Settings/RoutingSettings.cs | 2 +- .../Services/AgentService.CreateAgent.cs | 3 +- .../Services/AgentService.UpdateAgent.cs | 4 ++- .../ConversationService.SendMessage.cs | 2 +- .../Evaluations/EvaluatingService.cs | 2 +- .../Repository/FileRepository.cs | 22 ++++++++++--- .../Routing/Hooks/RoutingAgentHook.cs | 2 +- .../BotSharp.Core/Routing/RoutingService.cs | 2 +- .../Controllers/AgentController.cs | 8 +++++ .../ViewModels/Agents/AgentCreationModel.cs | 4 ++- .../ViewModels/Agents/AgentUpdateModel.cs | 5 ++- .../ViewModels/Agents/AgentViewModel.cs | 5 +++ .../Collections/AgentDocument.cs | 1 + .../Models/AgentLlmConfigMongoElement.cs | 31 +++++++++++++++++++ .../Repository/MongoRepository.cs | 28 ++++++++++++++--- .../RoutingConversationHook.cs | 2 +- .../Services/TwilioService.cs | 4 +-- 22 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs create mode 100644 src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs index 0a8b38e81..669ebabae 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs @@ -14,5 +14,6 @@ public enum AgentField Function, Template, Response, - Sample + Sample, + LlmConfig } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 4092f9c79..0a66f0b5b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -66,6 +66,12 @@ public class Agent public List RoutingRules { get; set; } = new List(); + /// + /// Agent LLM Config, i.e., provider & model + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public AgentLlmConfig? LlmConfig { get; set; } + /// /// For rendering deferral /// @@ -176,4 +182,10 @@ public Agent SetRoutingRules(List rules) RoutingRules = rules ?? new List(); return this; } + + public Agent SetLlmConfig(AgentLlmConfig? llmConfig) + { + LlmConfig = llmConfig; + return this; + } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs new file mode 100644 index 000000000..b920fcf97 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -0,0 +1,9 @@ +namespace BotSharp.Abstraction.Agents.Models; + +public class AgentLlmConfig +{ + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Provider { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string Model { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs b/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs index c08f4f71e..e67621fe9 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Evaluations/Settings/EvaluatorSetting.cs @@ -2,7 +2,7 @@ namespace BotSharp.Abstraction.Evaluations.Settings; public class EvaluatorSetting { - public string EvaluatorId { get; set; } + public string AgentId { get; set; } public string Provider { get; set; } public string Model { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs index c65ea62f5..18a20713e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs @@ -22,14 +22,14 @@ public RoutingContext(RoutingSettings setting) /// Agent that can handl user original goal. /// public string OriginAgentId - => _stack.Where(x => x != _setting.RouterId).Last(); + => _stack.Where(x => x != _setting.AgentId).Last(); public bool IsEmpty => !_stack.Any(); public string GetCurrentAgentId() { if (_stack.Count == 0) { - _stack.Push(_setting.RouterId); + _stack.Push(_setting.AgentId); } return _stack.Peek(); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs index 62a6ae4ac..bbe76a818 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Settings/RoutingSettings.cs @@ -5,7 +5,7 @@ public class RoutingSettings /// /// Router Agent Id /// - public string RouterId { get; set; } = string.Empty; + public string AgentId { get; set; } = string.Empty; public string Planner { get; set; } = string.Empty; public string Provider { get; set; } = string.Empty; diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs index be9ef6582..b88322dc5 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs @@ -39,7 +39,8 @@ public async Task CreateAgent(Agent agent) .SetInstruction(foundAgent.Instruction) .SetTemplates(foundAgent.Templates) .SetFunctions(foundAgent.Functions) - .SetResponses(foundAgent.Responses); + .SetResponses(foundAgent.Responses) + .SetLlmConfig(foundAgent.LlmConfig); } var user = _db.GetUserById(_user.Id); diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index 292b83bbe..e0a225e29 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -27,6 +27,7 @@ public async Task UpdateAgent(Agent agent, AgentField updateField) record.Templates = agent.Templates ?? new List(); record.Responses = agent.Responses ?? new List(); record.Samples = agent.Samples ?? new List(); + record.LlmConfig = agent.LlmConfig; _db.UpdateAgent(record, updateField); await Task.CompletedTask; @@ -58,7 +59,8 @@ public async Task UpdateAgentFromFile(string id) .SetTemplates(foundAgent.Templates) .SetFunctions(foundAgent.Functions) .SetResponses(foundAgent.Responses) - .SetSamples(foundAgent.Samples); + .SetSamples(foundAgent.Samples) + .SetLlmConfig(foundAgent.LlmConfig); _db.UpdateAgent(clonedAgent, AgentField.All); } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs index ad1faeef0..eebf4c006 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs @@ -59,7 +59,7 @@ public async Task SendMessage(string agentId, var routing = _services.GetRequiredService(); var settings = _services.GetRequiredService(); - response = agentId == settings.RouterId ? + response = agentId == settings.AgentId ? await routing.InstructLoop(message) : await routing.ExecuteDirectly(agent, message); diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs index 75191edfa..340b8f7e3 100644 --- a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs +++ b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs @@ -20,7 +20,7 @@ public EvaluatingService(IServiceProvider services, EvaluatorSetting settings) public async Task Execute(string task, EvaluationRequest request) { var agentService = _services.GetRequiredService(); - var evaluator = await agentService.GetAgent(_settings.EvaluatorId); + var evaluator = await agentService.GetAgent(_settings.AgentId); // Task execution mode evaluator.Instruction = evaluator.Templates.First(x => x.Name == "instruction.executor").Content; var taskPrompt = evaluator.Templates.First(x => x.Name == $"task.{task}").Content; diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index 8b90ae79f..c5b22d892 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -246,6 +246,9 @@ public void UpdateAgent(Agent agent, AgentField field) case AgentField.Sample: UpdateAgentSamples(agent.Id, agent.Samples); break; + case AgentField.LlmConfig: + UpdateAgentLlmConfig(agent.Id, agent.LlmConfig); + break; case AgentField.All: UpdateAgentAllFields(agent); break; @@ -431,6 +434,17 @@ private void UpdateAgentSamples(string agentId, List samples) File.WriteAllLines(file, samples); } + private void UpdateAgentLlmConfig(string agentId, AgentLlmConfig? config) + { + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + agent.LlmConfig = config; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } + private void UpdateAgentAllFields(Agent inputAgent) { var (agent, agentFile) = GetAgentFromFile(inputAgent.Id); @@ -493,10 +507,10 @@ public List GetAgentResponses(string agentId, string prefix, string inte var templates = FetchTemplates(dir); var responses = FetchResponses(dir); return record.SetInstruction(instruction) - .SetFunctions(functions) - .SetSamples(samples) - .SetTemplates(templates) - .SetResponses(responses); + .SetFunctions(functions) + .SetSamples(samples) + .SetTemplates(templates) + .SetResponses(responses); } return null; diff --git a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs index 07647e10f..2d3d3ab23 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs @@ -7,7 +7,7 @@ namespace BotSharp.Core.Routing.Hooks; public class RoutingAgentHook : AgentHookBase { private readonly RoutingSettings _routingSetting; - public override string SelfId => _routingSetting.RouterId; + public override string SelfId => _routingSetting.AgentId; public RoutingAgentHook(IServiceProvider services, AgentSettings settings, RoutingSettings routingSetting) : base(services, settings) diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs index a92e4a6e1..8304b46ef 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs @@ -64,7 +64,7 @@ public async Task ExecuteDirectly(Agent agent, RoleDialogModel public async Task InstructLoop(RoleDialogModel message) { var agentService = _services.GetRequiredService(); - _router = await agentService.LoadAgent(_settings.RouterId); + _router = await agentService.LoadAgent(_settings.AgentId); RoleDialogModel response = default; diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index eb84453cf..12d17e514 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -149,4 +149,12 @@ public async Task UpdateAgentSamples([FromRoute] string agentId, [FromBody] Agen model.Id = agentId; await _agentService.UpdateAgent(model, AgentField.Sample); } + + [HttpPut("/agent/{agentId}/llm-config")] + public async Task UpdateAgentLlmConfig([FromRoute] string agentId, [FromBody] AgentUpdateModel agent) + { + var model = agent.ToAgent(); + model.Id = agentId; + await _agentService.UpdateAgent(model, AgentField.LlmConfig); + } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs index 9af1dda69..fe6ce7e26 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -43,6 +43,7 @@ public class AgentCreationModel /// public List Profiles { get; set; } = new List(); public List RoutingRules { get; set; } = new List(); + public AgentLlmConfig? LlmConfig { get; set; } public Agent ToAgent() { @@ -61,7 +62,8 @@ public Agent ToAgent() Profiles = Profiles, RoutingRules = RoutingRules? .Select(x => RoutingRuleUpdateModel.ToDomainElement(x))? - .ToList() ?? new List() + .ToList() ?? new List(), + LlmConfig = LlmConfig }; } } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs index c340b57a1..b394b3bbd 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -47,6 +47,8 @@ public class AgentUpdateModel public List? RoutingRules { get; set; } + public AgentLlmConfig? LlmConfig { get; set; } + public Agent ToAgent() { var agent = new Agent() @@ -63,7 +65,8 @@ public Agent ToAgent() Instruction = Instruction ?? string.Empty, Templates = Templates ?? new List(), Functions = Functions ?? new List(), - Responses = Responses ?? new List() + Responses = Responses ?? new List(), + LlmConfig = LlmConfig }; return agent; diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index 2ef67efd7..c09f417a8 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -26,6 +26,10 @@ public class AgentViewModel [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List RoutingRules { get; set; } + [JsonPropertyName("llmConfig")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public AgentLlmConfig? LlmConfig { get; set; } + [JsonPropertyName("created_datetime")] public DateTime CreatedDateTime { get; set; } @@ -49,6 +53,7 @@ public static AgentViewModel FromAgent(Agent agent) AllowRouting = agent.AllowRouting, Profiles = agent.Profiles, RoutingRules = agent.RoutingRules, + LlmConfig = agent.LlmConfig, CreatedDateTime = agent.CreatedDateTime, UpdatedDateTime = agent.UpdatedDateTime }; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs index 5e7c2f35c..c9e7298b0 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs @@ -16,6 +16,7 @@ public class AgentDocument : MongoBase public bool Disabled { get; set; } public List Profiles { get; set; } public List RoutingRules { get; set; } + public AgentLlmConfigMongoElement? LlmConfig { get; set; } public DateTime CreatedTime { get; set; } public DateTime UpdatedTime { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs new file mode 100644 index 000000000..f5217fd59 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs @@ -0,0 +1,31 @@ +using BotSharp.Abstraction.Agents.Models; + +namespace BotSharp.Plugin.MongoStorage.Models; + +public class AgentLlmConfigMongoElement +{ + public string? Provider { get; set; } + public string Model { get; set; } + + public static AgentLlmConfigMongoElement? ToMongoElement(AgentLlmConfig? config) + { + if (config == null) return null; + + return new AgentLlmConfigMongoElement + { + Provider = config.Provider, + Model = config.Model + }; + } + + public static AgentLlmConfig? ToDomainElement(AgentLlmConfigMongoElement? config) + { + if (config == null) return null; + + return new AgentLlmConfig + { + Provider = config.Provider, + Model = config.Model + }; + } +} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index cc7ea6e08..0dc83366b 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -82,6 +82,7 @@ public int Transaction(Action action) RoutingRules = x.RoutingRules? .Select(r => RoutingRuleMongoElement.ToMongoElement(r))? .ToList() ?? new List(), + LlmConfig = AgentLlmConfigMongoElement.ToMongoElement(x.LlmConfig), CreatedTime = x.CreatedDateTime, UpdatedTime = x.UpdatedDateTime }).ToList(); @@ -102,6 +103,7 @@ public int Transaction(Action action) .Set(x => x.Disabled, agent.Disabled) .Set(x => x.Profiles, agent.Profiles) .Set(x => x.RoutingRules, agent.RoutingRules) + .Set(x => x.LlmConfig, agent.LlmConfig) .Set(x => x.CreatedTime, agent.CreatedTime) .Set(x => x.UpdatedTime, agent.UpdatedTime); _dc.Agents.UpdateOne(filter, update, _options); @@ -211,6 +213,9 @@ public void UpdateAgent(Agent agent, AgentField field) case AgentField.Sample: UpdateAgentSamples(agent.Id, agent.Samples); break; + case AgentField.LlmConfig: + UpdateAgentLlmConfig(agent.Id, agent.LlmConfig); + break; case AgentField.All: UpdateAgentAllFields(agent); break; @@ -362,6 +367,17 @@ private void UpdateAgentSamples(string agentId, List samples) _dc.Agents.UpdateOne(filter, update); } + private void UpdateAgentLlmConfig(string agentId, AgentLlmConfig? config) + { + var llmConfig = AgentLlmConfigMongoElement.ToMongoElement(config); + var filter = Builders.Filter.Eq(x => x.Id, agentId); + var update = Builders.Update + .Set(x => x.LlmConfig, llmConfig) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + private void UpdateAgentAllFields(Agent agent) { var filter = Builders.Filter.Eq(x => x.Id, agent.Id); @@ -377,6 +393,7 @@ private void UpdateAgentAllFields(Agent agent) .Set(x => x.Functions, agent.Functions.Select(f => FunctionDefMongoElement.ToMongoElement(f)).ToList()) .Set(x => x.Responses, agent.Responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList()) .Set(x => x.Samples, agent.Samples) + .Set(x => x.LlmConfig, AgentLlmConfigMongoElement.ToMongoElement(agent.LlmConfig)) .Set(x => x.IsPublic, agent.IsPublic) .Set(x => x.UpdatedTime, DateTime.UtcNow); @@ -413,7 +430,8 @@ private void UpdateAgentAllFields(Agent agent) Profiles = agent.Profiles, RoutingRules = !agent.RoutingRules.IsNullOrEmpty() ? agent.RoutingRules .Select(r => RoutingRuleMongoElement.ToDomainElement(agent.Id, agent.Name, r)) - .ToList() : new List() + .ToList() : new List(), + LlmConfig = AgentLlmConfigMongoElement.ToDomainElement(agent.LlmConfig) }; } @@ -469,7 +487,8 @@ public List GetAgents(AgentFilter filter) Profiles = x.Profiles, RoutingRules = !x.RoutingRules.IsNullOrEmpty() ? x.RoutingRules .Select(r => RoutingRuleMongoElement.ToDomainElement(x.Id, x.Name, r)) - .ToList() : new List() + .ToList() : new List(), + LlmConfig = AgentLlmConfigMongoElement.ToDomainElement(x.LlmConfig) }).ToList(); } @@ -482,8 +501,8 @@ join u in _dc.Users.AsQueryable() on ua.UserId equals u.Id var filter = new AgentFilter { - IsPublic = true, - AgentIds = agentIds + AgentIds = agentIds, + IsPublic = true }; var agents = GetAgents(filter); return agents; @@ -533,6 +552,7 @@ public void BulkInsertAgents(List agents) RoutingRules = x.RoutingRules? .Select(r => RoutingRuleMongoElement.ToMongoElement(r))? .ToList() ?? new List(), + LlmConfig = AgentLlmConfigMongoElement.ToMongoElement(x.LlmConfig), CreatedTime = x.CreatedDateTime, UpdatedTime = x.UpdatedDateTime }).ToList(); diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs index 368f49bfa..11744d0d5 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs @@ -53,7 +53,7 @@ public override async Task OnMessageReceived(RoleDialogModel message) public override async Task OnResponseGenerated(RoleDialogModel message) { var routerSettings = _services.GetRequiredService(); - bool saveFlag = message.CurrentAgentId != routerSettings.RouterId; + bool saveFlag = message.CurrentAgentId != routerSettings.AgentId; if (saveFlag) { diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs index dcbcf30c0..374a00ad0 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs @@ -56,7 +56,7 @@ public VoiceResponse ReturnInstructions(string message) { Gather.InputEnum.Speech }, - Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}") + Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.AgentId}") }; gather.Say(message); response.Append(gather); @@ -82,7 +82,7 @@ public VoiceResponse HoldOn(int interval, string message = null) var gather = new Gather() { Input = new List() { Gather.InputEnum.Speech }, - Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.RouterId}"), + Action = new Uri($"{_settings.CallbackHost}/twilio/voice/{routingSetting.AgentId}"), ActionOnEmptyResult = true }; if (!string.IsNullOrEmpty(message)) From 258be22d3644dfc3586bf715ed74228405cd9c7f Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 13 Dec 2023 14:33:36 -0600 Subject: [PATCH 3/4] remove code --- .../BotSharp.Abstraction/Agents/Models/Agent.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 7cf8750dd..965c22849 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -14,6 +14,7 @@ public class Agent /// /// Default LLM settings /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public AgentLlmConfig? LlmConfig { get; set; } /// @@ -71,12 +72,6 @@ public class Agent public List RoutingRules { get; set; } = new List(); - /// - /// Agent LLM Config, i.e., provider & model - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public AgentLlmConfig? LlmConfig { get; set; } - /// /// For rendering deferral /// From d6e741957e00f1e666223bc28a3ee0333c4d777b Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 13 Dec 2023 14:41:47 -0600 Subject: [PATCH 4/4] minor change --- src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs | 1 + .../BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs | 2 ++ .../Models/AgentLlmConfigMongoElement.cs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 965c22849..f6e10fd08 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -100,6 +100,7 @@ public static Agent Clone(Agent agent) AllowRouting = agent.AllowRouting, Profiles = agent.Profiles, RoutingRules = agent.RoutingRules, + LlmConfig = agent.LlmConfig, CreatedDateTime = agent.CreatedDateTime, UpdatedDateTime = agent.UpdatedDateTime, }; diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs index 5b075f35d..266f14f2e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -6,11 +6,13 @@ public class AgentLlmConfig /// Completion Provider /// [JsonPropertyName("provider")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Provider { get; set; } /// /// Model name /// [JsonPropertyName("model")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Model { get; set; } } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs index f5217fd59..70c770971 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs @@ -5,7 +5,7 @@ namespace BotSharp.Plugin.MongoStorage.Models; public class AgentLlmConfigMongoElement { public string? Provider { get; set; } - public string Model { get; set; } + public string? Model { get; set; } public static AgentLlmConfigMongoElement? ToMongoElement(AgentLlmConfig? config) {