From a3f8099b8d8311ea0aa5f4d2402f822aa005f5d9 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Mon, 11 Mar 2024 22:01:40 +0800 Subject: [PATCH 1/3] feat: add sparkdesk plugin --- BotSharp.sln | 13 +- .../BotSharp.Plugin.SparkDesk.csproj | 21 ++ .../Providers/ChatCompletionProvider.cs | 244 ++++++++++++++++++ .../Settings/SparkDeskSettings.cs | 12 + .../SparkDeskPlugin.cs | 27 ++ .../BotSharp.Plugin.SparkDesk/Using.cs | 17 ++ src/WebStarter/WebStarter.csproj | 1 + 7 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 src/Plugins/BotSharp.Plugin.SparkDesk/BotSharp.Plugin.SparkDesk.csproj create mode 100644 src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs create mode 100644 src/Plugins/BotSharp.Plugin.SparkDesk/Settings/SparkDeskSettings.cs create mode 100644 src/Plugins/BotSharp.Plugin.SparkDesk/SparkDeskPlugin.cs create mode 100644 src/Plugins/BotSharp.Plugin.SparkDesk/Using.cs diff --git a/BotSharp.sln b/BotSharp.sln index 0c99deee..b04cd1c7 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -81,7 +81,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.HttpHandler EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.SqlDriver", "src\Plugins\BotSharp.Plugin.SqlDriver\BotSharp.Plugin.SqlDriver.csproj", "{D775DB67-A4B4-44E5-9144-522689590057}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.Dashboard", "src\Plugins\BotSharp.Plugin.Dashboard\BotSharp.Plugin.Dashboard.csproj", "{267998C1-55C2-4ADC-8361-2CDFA5EA6D6C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.Dashboard", "src\Plugins\BotSharp.Plugin.Dashboard\BotSharp.Plugin.Dashboard.csproj", "{267998C1-55C2-4ADC-8361-2CDFA5EA6D6C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.SparkDesk", "src\Plugins\BotSharp.Plugin.SparkDesk\BotSharp.Plugin.SparkDesk.csproj", "{289E25C8-63F1-4D52-9909-207724DB40CB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -323,6 +325,14 @@ Global {267998C1-55C2-4ADC-8361-2CDFA5EA6D6C}.Release|Any CPU.Build.0 = Release|Any CPU {267998C1-55C2-4ADC-8361-2CDFA5EA6D6C}.Release|x64.ActiveCfg = Release|Any CPU {267998C1-55C2-4ADC-8361-2CDFA5EA6D6C}.Release|x64.Build.0 = Release|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Debug|x64.ActiveCfg = Debug|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Debug|x64.Build.0 = Debug|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Release|Any CPU.Build.0 = Release|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Release|x64.ActiveCfg = Release|Any CPU + {289E25C8-63F1-4D52-9909-207724DB40CB}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -364,6 +374,7 @@ Global {32D9E720-6FE6-4F29-94B1-B10B05BFAD75} = {51AFE054-AE99-497D-A593-69BAEFB5106F} {D775DB67-A4B4-44E5-9144-522689590057} = {51AFE054-AE99-497D-A593-69BAEFB5106F} {267998C1-55C2-4ADC-8361-2CDFA5EA6D6C} = {51AFE054-AE99-497D-A593-69BAEFB5106F} + {289E25C8-63F1-4D52-9909-207724DB40CB} = {D5293208-2BEF-42FC-A64C-5954F61720BA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/BotSharp.Plugin.SparkDesk.csproj b/src/Plugins/BotSharp.Plugin.SparkDesk/BotSharp.Plugin.SparkDesk.csproj new file mode 100644 index 00000000..b7bd9f09 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/BotSharp.Plugin.SparkDesk.csproj @@ -0,0 +1,21 @@ + + + + netstandard2.1 + enable + $(LangVersion) + $(BotSharpVersion) + $(GeneratePackageOnBuild) + $(GenerateDocumentationFile) + $(SolutionDir)packages + + + + + + + + + + + diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs new file mode 100644 index 00000000..12549096 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs @@ -0,0 +1,244 @@ +using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Loggers; +using BotSharp.Abstraction.Routing; + +namespace BotSharp.Plugin.SparkDesk.Providers; + +public class ChatCompletionProvider : IChatCompletion +{ + public string Provider => "sparkdesk"; + + private readonly SparkDeskSettings _settings; + private readonly IServiceProvider _services; + private readonly ILogger _logger; + private string _model; + + public ChatCompletionProvider(IServiceProvider services, + SparkDeskSettings settings, + ILogger logger) + { + _services = services; + _settings = settings; + _logger = logger; + _model = $"general{settings.ModelVersion.ToString()}"; + } + + + public async Task GetChatCompletions(Agent agent, List conversations) + { + var contentHooks = _services.GetServices().ToList(); + + // Before chat completion hook + foreach (var hook in contentHooks) + { + await hook.BeforeGenerating(agent, conversations); + } + + var client = new SparkDeskClient(appId: _settings.AppId, apiKey: _settings.ApiKey, apiSecret: _settings.ApiSecret); + var (prompt, messages, funcall) = PrepareOptions(agent, conversations); + + var response = await client.ChatAsync(modelVersion:_settings.ModelVersion, messages,functions:funcall); + + var responseMessage = new RoleDialogModel(AgentRole.Assistant, response.Text) + { + CurrentAgentId = agent.Id, + MessageId = conversations.Last().MessageId + }; + + if (response.FunctionCall != null) + { + responseMessage = new RoleDialogModel(AgentRole.Function, response.Text) + { + CurrentAgentId = agent.Id, + MessageId = conversations.Last().MessageId, + FunctionName = response.FunctionCall.Name, + FunctionArgs = response.FunctionCall.Arguments + }; + + // Somethings LLM will generate a function name with agent name. + if (!string.IsNullOrEmpty(responseMessage.FunctionName)) + { + responseMessage.FunctionName = responseMessage.FunctionName.Split('.').Last(); + } + } + + // After chat completion hook + foreach (var hook in contentHooks) + { + await hook.AfterGenerated(responseMessage, new TokenStatsModel + { + Prompt = prompt, + Provider = Provider, + Model = _model, + PromptCount = response.Usage.PromptTokens, + CompletionCount = response.Usage.CompletionTokens + }); + } + + return responseMessage; + } + + + + public async Task GetChatCompletionsAsync(Agent agent, List conversations, Func onMessageReceived, Func onFunctionExecuting) + { + var hooks = _services.GetServices().ToList(); + + // Before chat completion hook + foreach (var hook in hooks) + { + await hook.BeforeGenerating(agent, conversations); + } + + var client = new SparkDeskClient(appId: _settings.AppId, apiKey: _settings.ApiKey, apiSecret: _settings.ApiSecret); + var (prompt, messages, funcall) = PrepareOptions(agent, conversations); + + var response = await client.ChatAsync(modelVersion: _settings.ModelVersion, messages, functions: funcall); + + var msg = new RoleDialogModel(AgentRole.Assistant, response.Text) + { + CurrentAgentId = agent.Id + }; + + // After chat completion hook + foreach (var hook in hooks) + { + await hook.AfterGenerated(msg, new TokenStatsModel + { + Prompt = prompt, + Provider = Provider, + Model = _model, + PromptCount = response.Usage.PromptTokens, + CompletionCount = response.Usage.CompletionTokens + }); + } + + if (response.FunctionCall != null) + { + _logger.LogInformation($"[{agent.Name}]: {response.FunctionCall.Name}({response.FunctionCall.Arguments})"); + + var funcContextIn = new RoleDialogModel(AgentRole.Function, response.Text) + { + CurrentAgentId = agent.Id, + FunctionName = response.FunctionCall.Name, + FunctionArgs = response.FunctionCall.Arguments + }; + + // Somethings LLM will generate a function name with agent name. + if (!string.IsNullOrEmpty(funcContextIn.FunctionName)) + { + funcContextIn.FunctionName = funcContextIn.FunctionName.Split('.').Last(); + } + + // Execute functions + await onFunctionExecuting(funcContextIn); + } + else + { + // Text response received + await onMessageReceived(msg); + } + + return true; + } + + public async Task GetChatCompletionsStreamingAsync(Agent agent, List conversations, Func onMessageReceived) + { + var client = new SparkDeskClient(appId: _settings.AppId, apiKey: _settings.ApiKey, apiSecret: _settings.ApiSecret); + var (prompt, messages, funcall) = PrepareOptions(agent, conversations); + + await foreach (StreamedChatResponse response in client.ChatAsStreamAsync(modelVersion: _settings.ModelVersion, messages, functions: funcall)) + { + if (response.FunctionCall !=null) + { + //Console.Write(choice.FunctionArgumentsUpdate); + + await onMessageReceived(new RoleDialogModel(AgentRole.Function, response.Text) + { + CurrentAgentId = agent.Id, + FunctionName = response.FunctionCall.Name, + FunctionArgs = response.FunctionCall.Arguments + }); + continue; + } + + await onMessageReceived(new RoleDialogModel(AgentRole.Assistant, response.Text) + { + CurrentAgentId = agent.Id + }); + + } + + return true; + } + + public void SetModelName(string model) + { + _model = model; + } + + private (string, ChatMessage[], FunctionDef[]?) PrepareOptions(Agent agent, List conversations) + { + var prompt = ""; + var functions = new List(); + var agentService = _services.GetRequiredService(); + + if (!string.IsNullOrEmpty(agent.Instruction)) + { + prompt += agentService.RenderedInstruction(agent); + } + + var routing = _services.GetRequiredService(); + var router = routing.Router; + + var messages = conversations.Select(c => new ChatMessage(c.Role == AgentRole.User ? "user" : "AI", c.Content)) + .ToList(); + + if (agent.Functions != null && agent.Functions.Count > 0) + { + foreach (var function in agent.Functions) + { + functions.Add(ConvertToFunctionDef(function)); + } + prompt += "\r\n\r\n[Conversations]\r\n"; + foreach (var dialog in conversations) + { + prompt += dialog.Role == AgentRole.Function ? + $"{dialog.Role}: {dialog.FunctionName} => {dialog.Content}\r\n" : + $"{dialog.Role}: {dialog.Content}\r\n"; + } + + prompt += "\r\n\r\n" + router.Templates.FirstOrDefault(x => x.Name == "response_with_function").Content; + + return (prompt, new List + { + new ChatMessage("Which function should be used for the next step based on latest user or function response, output your response in JSON:", AgentRole.User), + }.ToArray(), functions.ToArray()); + } + + return (prompt, messages.ToArray(), null); + } + + private FunctionDef ConvertToFunctionDef(BotSharp.Abstraction.Functions.Models.FunctionDef def) + { + var parameters = def.Parameters; + var funcParamsProperties = parameters.Properties; + var requiredList = parameters.Required; + var fundef = new List(); + if (funcParamsProperties != null) + { + var props = funcParamsProperties.RootElement.EnumerateObject(); + while (props.MoveNext()) + { + var prop = props.Current; + var name = prop.Name; + bool required = requiredList.Contains(name); + FunctionParametersDef parametersDef = new FunctionParametersDef(name, prop.Value.GetProperty("type").GetRawText(), prop.Value.GetProperty("description").GetRawText(), required); + fundef.Add(parametersDef); + } + } + FunctionDef functionDef = new FunctionDef(def.Name, def.Description, fundef.ToArray()); + return functionDef; + } +} diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/Settings/SparkDeskSettings.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/Settings/SparkDeskSettings.cs new file mode 100644 index 00000000..d15833b4 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/Settings/SparkDeskSettings.cs @@ -0,0 +1,12 @@ +namespace BotSharp.Plugin.SparkDesk; + +public class SparkDeskSettings +{ + public string AppId { get; set; } + + public string ApiKey { get; set; } + + public string ApiSecret { get; set; } + + public ModelVersion ModelVersion { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/SparkDeskPlugin.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/SparkDeskPlugin.cs new file mode 100644 index 00000000..3bcd3fa6 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/SparkDeskPlugin.cs @@ -0,0 +1,27 @@ +using BotSharp.Plugin.SparkDesk.Providers; + +namespace BotSharp.Plugin.SparkDesk; + +public class SparkDeskPlugin : IBotSharpPlugin +{ + public string Id => "93ad041b-a99e-5766-946e-6a8cc2d4dd4f"; + + public string Name => "sparkdesk"; + public string Description => "xfyun sparkdesk Service including text generation services."; + public SettingsMeta Settings => new SettingsMeta("SparkDesk"); + + public object GetNewSettingsInstance() + { + return new SparkDeskSettings(); + } + + public void RegisterDI(IServiceCollection services, IConfiguration config) + { + services.AddScoped(provider => + { + var settingService = provider.GetRequiredService(); + return settingService.Bind("SparkDesk"); + }); + services.AddScoped(); + } +} diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/Using.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/Using.cs new file mode 100644 index 00000000..b266d1d2 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/Using.cs @@ -0,0 +1,17 @@ +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 Microsoft.Extensions.Logging; +global using System.Text.Json.Serialization; +global using BotSharp.Abstraction.Utilities; +global using BotSharp.Abstraction.Plugins; +global using BotSharp.Abstraction.Settings; +global using Sdcb.SparkDesk; \ No newline at end of file diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index 85d2d24b..913bd83c 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -28,6 +28,7 @@ + From 9037d09585f87c8d04841de94b2a22d0f7028475 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Fri, 15 Mar 2024 15:00:16 +0800 Subject: [PATCH 2/3] feat: Refactor ChatCompletion --- .../Providers/ChatCompletionProvider.cs | 109 +++++++++++------- .../Providers/ProviderHelper.cs | 31 +++++ 2 files changed, 100 insertions(+), 40 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ProviderHelper.cs diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs index 12549096..e6e11289 100644 --- a/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs @@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.Routing; +using Sdcb.SparkDesk.ResponseInternals; namespace BotSharp.Plugin.SparkDesk.Providers; @@ -38,7 +39,7 @@ public class ChatCompletionProvider : IChatCompletion var client = new SparkDeskClient(appId: _settings.AppId, apiKey: _settings.ApiKey, apiSecret: _settings.ApiSecret); var (prompt, messages, funcall) = PrepareOptions(agent, conversations); - var response = await client.ChatAsync(modelVersion:_settings.ModelVersion, messages,functions:funcall); + var response = await client.ChatAsync(modelVersion:_settings.ModelVersion, messages,functions: funcall.Length == 0 ? null : funcall); var responseMessage = new RoleDialogModel(AgentRole.Assistant, response.Text) { @@ -55,12 +56,7 @@ public class ChatCompletionProvider : IChatCompletion FunctionName = response.FunctionCall.Name, FunctionArgs = response.FunctionCall.Arguments }; - - // Somethings LLM will generate a function name with agent name. - if (!string.IsNullOrEmpty(responseMessage.FunctionName)) - { - responseMessage.FunctionName = responseMessage.FunctionName.Split('.').Last(); - } + } // After chat completion hook @@ -94,7 +90,7 @@ public class ChatCompletionProvider : IChatCompletion var client = new SparkDeskClient(appId: _settings.AppId, apiKey: _settings.ApiKey, apiSecret: _settings.ApiSecret); var (prompt, messages, funcall) = PrepareOptions(agent, conversations); - var response = await client.ChatAsync(modelVersion: _settings.ModelVersion, messages, functions: funcall); + var response = await client.ChatAsync(modelVersion: _settings.ModelVersion, messages, functions: funcall.Length == 0 ?null: funcall); var msg = new RoleDialogModel(AgentRole.Assistant, response.Text) { @@ -148,12 +144,10 @@ public class ChatCompletionProvider : IChatCompletion var client = new SparkDeskClient(appId: _settings.AppId, apiKey: _settings.ApiKey, apiSecret: _settings.ApiSecret); var (prompt, messages, funcall) = PrepareOptions(agent, conversations); - await foreach (StreamedChatResponse response in client.ChatAsStreamAsync(modelVersion: _settings.ModelVersion, messages, functions: funcall)) + await foreach (StreamedChatResponse response in client.ChatAsStreamAsync(modelVersion: _settings.ModelVersion, messages, functions: funcall.Length == 0 ? null : funcall)) { if (response.FunctionCall !=null) { - //Console.Write(choice.FunctionArgumentsUpdate); - await onMessageReceived(new RoleDialogModel(AgentRole.Function, response.Text) { CurrentAgentId = agent.Id, @@ -180,44 +174,79 @@ public class ChatCompletionProvider : IChatCompletion private (string, ChatMessage[], FunctionDef[]?) PrepareOptions(Agent agent, List conversations) { - var prompt = ""; var functions = new List(); var agentService = _services.GetRequiredService(); + var messages = new List(); if (!string.IsNullOrEmpty(agent.Instruction)) { - prompt += agentService.RenderedInstruction(agent); + var instruction = agentService.RenderedInstruction(agent); + messages.Add(ChatMessage.FromSystem(instruction)); } - - var routing = _services.GetRequiredService(); - var router = routing.Router; - - var messages = conversations.Select(c => new ChatMessage(c.Role == AgentRole.User ? "user" : "AI", c.Content)) - .ToList(); - - if (agent.Functions != null && agent.Functions.Count > 0) + if (!string.IsNullOrEmpty(agent.Knowledges)) { - foreach (var function in agent.Functions) - { - functions.Add(ConvertToFunctionDef(function)); - } - prompt += "\r\n\r\n[Conversations]\r\n"; - foreach (var dialog in conversations) - { - prompt += dialog.Role == AgentRole.Function ? - $"{dialog.Role}: {dialog.FunctionName} => {dialog.Content}\r\n" : - $"{dialog.Role}: {dialog.Content}\r\n"; - } - - prompt += "\r\n\r\n" + router.Templates.FirstOrDefault(x => x.Name == "response_with_function").Content; - - return (prompt, new List - { - new ChatMessage("Which function should be used for the next step based on latest user or function response, output your response in JSON:", AgentRole.User), - }.ToArray(), functions.ToArray()); + messages.Add(ChatMessage.FromSystem(agent.Knowledges)); + } + var samples = ProviderHelper.GetChatSamples(agent.Samples); + foreach (var message in samples) + { + messages.Add(message.Role == AgentRole.User ? + ChatMessage.FromUser(message.Content) : + ChatMessage.FromAssistant(message.Content)); } - return (prompt, messages.ToArray(), null); + foreach (var function in agent.Functions) + { + functions.Add(ConvertToFunctionDef(function)); + } + + foreach (var message in conversations) + { + if (message.Role == "function") + { + messages.Add(ChatMessage.FromUser($"function call result: {message.Content}")); + } + else if (message.Role == "user") + { + var userMessage = ChatMessage.FromUser(message.Content); + + messages.Add(userMessage); + } + else if (message.Role == "assistant") + { + messages.Add(ChatMessage.FromAssistant(message.Content)); + } + } + + var prompt = GetPrompt(messages, functions); + return (prompt, messages.ToArray(), functions.ToArray()); + } + + private string GetPrompt(List messages,List functions) + { + var prompt = string.Empty; + + if (messages.Count > 0) + { + // System instruction + var verbose = string.Join("\r\n", messages + .Where(x => x.Role == AgentRole.System) + .Select(x => + { + return $"{x.Role}: {x.Content}"; + })); + prompt += $"{verbose}\r\n"; + + verbose = string.Join("\r\n", messages + .Where(x => x.Role != AgentRole.System).Select(x => + { + return + $"{x.Role}: {x.Content}"; + + })); + prompt += $"\r\n{verbose}\r\n"; + } + return prompt; } private FunctionDef ConvertToFunctionDef(BotSharp.Abstraction.Functions.Models.FunctionDef def) diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ProviderHelper.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ProviderHelper.cs new file mode 100644 index 00000000..efeca634 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ProviderHelper.cs @@ -0,0 +1,31 @@ +namespace BotSharp.Plugin.SparkDesk.Providers; + +public class ProviderHelper +{ + + public static List GetChatSamples(List lines) + { + var samples = new List(); + + for (int i = 0; i < lines.Count; i++) + { + var line = lines[i]; + if (string.IsNullOrEmpty(line.Trim())) + { + continue; + } + var role = line.Substring(0, line.IndexOf(' ') - 1).Trim(); + var content = line.Substring(line.IndexOf(' ') + 1).Trim(); + + // comments + if (role == "##") + { + continue; + } + + samples.Add(new RoleDialogModel(role, content)); + } + + return samples; + } +} From 1f5ec6020782141ee606178dc7b61a949c0c98ea Mon Sep 17 00:00:00 2001 From: geffzhang Date: Mon, 18 Mar 2024 20:54:00 +0800 Subject: [PATCH 3/3] feat: add sparkdesk config --- .../Providers/ChatCompletionProvider.cs | 2 +- src/WebStarter/appsettings.json | 23 +++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs index e6e11289..3423347e 100644 --- a/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SparkDesk/Providers/ChatCompletionProvider.cs @@ -204,7 +204,7 @@ public class ChatCompletionProvider : IChatCompletion { if (message.Role == "function") { - messages.Add(ChatMessage.FromUser($"function call result: {message.Content}")); + //messages.Add(ChatMessage.FromUser($"function call result: {message.Content}")); } else if (message.Role == "user") { diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 694cfccb..46340bc3 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -45,7 +45,7 @@ "Name": "gpt-35-turbo", "Version": "1106", "ApiKey": "", - "Endpoint": "https://gpt-35-turbo.openai.azure.com/", + "Endpoint": "https://gpt-35-turbo-instruct.openai.azure.com/", "Type": "chat", "PromptCost": 0.0015, "CompletionCost": 0.002 @@ -82,6 +82,17 @@ "Type": "text" } ] + }, + { + "Provider": "sparkdesk", + "Models": [ + { + "Name": "gpt-35-turbo", + "Type": "chat", + "PromptCost": 0.0015, + "CompletionCost": 0.002 + } + ] } ], @@ -197,6 +208,13 @@ "Pdf2TextConverter": "PigPdf2TextConverter" }, + "SparkDesk": { + "AppId": "", + "ApiKey": "", + "ApiSecret": "", + "ModelVersion": "V3_5" + }, + "PluginLoader": { "Assemblies": [ "BotSharp.Core", @@ -214,7 +232,8 @@ "BotSharp.Plugin.WeChat", "BotSharp.Plugin.PizzaBot", "BotSharp.Plugin.WebDriver", - "BotSharp.Plugin.LLamaSharp" + "BotSharp.Plugin.LLamaSharp", + "BotSharp.Plugin.SparkDesk" ] } }