diff --git a/docs/architecture/assets/diagram.drawio b/docs/architecture/assets/diagram.drawio deleted file mode 100644 index 291cd8f2..00000000 --- a/docs/architecture/assets/diagram.drawio +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/architecture/assets/overview.drawio b/docs/architecture/assets/overview.drawio index b6dacd1a..bfb06fbf 100644 --- a/docs/architecture/assets/overview.drawio +++ b/docs/architecture/assets/overview.drawio @@ -1,71 +1,80 @@ - + - + - + - + - + - + - + - - + + - - + + - - + + - + - + - + - - + + - - + + - - + + - + - + - + - - + + - - + + - - + + + + + + + + + + + diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs new file mode 100644 index 00000000..447bef04 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs @@ -0,0 +1,29 @@ +namespace BotSharp.Abstraction.Conversations.Models; + +public class IncomingMessageModel +{ + public string Text { get; set; } = string.Empty; + + public virtual string Channel { get; set; } = string.Empty; + + /// + /// Model name + /// + public virtual string ModelName { get; set; } = "gpt-3.5-turbo"; + + /// + /// The sampling temperature to use that controls the apparent creativity of generated completions. + /// + public float Temperature { get; set; } = 0.5f; + + /// + /// An alternative value to Temperature, called nucleus sampling, that causes + /// the model to consider the results of the tokens with probability mass. + /// + public float SamplingFactor { get; set; } = 0.5f; + + /// + /// Conversation states from input + /// + public List States { get; set; } = new List(); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs index eda9445c..cc05fa7f 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -13,6 +13,7 @@ public class RoleDialogModel public string CurrentAgentId { get; set; } public string ModelName { get; set; } = "gpt-3.5-turbo"; public float Temperature { get; set; } = 0.5f; + public float SamplingFactor { get; set; } = 0.5f; /// /// Function name if LLM response function call diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs index ee305239..3e7b9cbe 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Templating; @@ -32,7 +33,9 @@ public partial class ConversationService await HandleAssistantMessage(agent, new RoleDialogModel(AgentRole.Assistant, text) { CurrentAgentId = agent.Id, - Channel = wholeDialogs.Last().Channel + Channel = wholeDialogs.Last().Channel, + Temperature = wholeDialogs.Last().Temperature, + SamplingFactor = wholeDialogs.Last().SamplingFactor }, onMessageReceived); return false; @@ -53,7 +56,9 @@ public partial class ConversationService await HandleAssistantMessage(agent, new RoleDialogModel(AgentRole.Assistant, fn.Content) { CurrentAgentId = fn.CurrentAgentId, - Channel = fn.Channel + Channel = fn.Channel, + Temperature = fn.Temperature, + SamplingFactor = fn.SamplingFactor }, onMessageReceived); return; @@ -65,7 +70,9 @@ public partial class ConversationService CurrentAgentId = fn.CurrentAgentId, Channel = fn.Channel, ExecutionData = fn.ExecutionData, - ExecutionResult = fn.ExecutionResult + ExecutionResult = fn.ExecutionResult, + Temperature = fn.Temperature, + SamplingFactor = fn.SamplingFactor }, onMessageReceived); return; @@ -97,7 +104,9 @@ public partial class ConversationService await HandleAssistantMessage(agent, new RoleDialogModel(AgentRole.Assistant, response) { CurrentAgentId = agent.Id, - Channel = wholeDialogs.Last().Channel + Channel = wholeDialogs.Last().Channel, + Temperature = wholeDialogs.Last().Temperature, + SamplingFactor = wholeDialogs.Last().SamplingFactor }, onMessageReceived); return; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs index 7ba6234c..2b42dd48 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs @@ -41,9 +41,15 @@ public partial class ConversationService // Interrupted by hook if (lastDialog.StopCompletion) { - var response = new RoleDialogModel(AgentRole.Assistant, lastDialog.Content); - await onMessageReceived(response); - _storage.Append(_conversationId, response); + var message = new RoleDialogModel(AgentRole.Assistant, lastDialog.Content) + { + CurrentAgentId = agent.Id, + Channel = lastDialog.Channel, + Temperature = lastDialog.Temperature, + SamplingFactor = lastDialog.SamplingFactor + }; + await onMessageReceived(message); + _storage.Append(_conversationId, message); return true; } } @@ -60,7 +66,9 @@ public partial class ConversationService await HandleAssistantMessage(agent, new RoleDialogModel(AgentRole.Assistant, reasonedContext.Content) { CurrentAgentId = agent.Id, - Channel = lastDialog.Channel + Channel = lastDialog.Channel, + Temperature = lastDialog.Temperature, + SamplingFactor = lastDialog.SamplingFactor }, onMessageReceived); return true; @@ -70,7 +78,9 @@ public partial class ConversationService await HandleAssistantMessage(agent, new RoleDialogModel(AgentRole.Assistant, reasonedContext.Content) { CurrentAgentId = agent.Id, - Channel = lastDialog.Channel + Channel = lastDialog.Channel, + Temperature = lastDialog.Temperature, + SamplingFactor = lastDialog.SamplingFactor }, onMessageReceived); return true; diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs index fdf6d256..77148d26 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs @@ -53,7 +53,9 @@ public class ConversationController : ControllerBase, IApiAdapter new RoleDialogModel("user", input.Text) { Channel = input.Channel, - ModelName = input.ModelName + ModelName = input.ModelName, + Temperature = input.Temperature, + SamplingFactor = input.SamplingFactor }, async msg => { diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs index 18bb130f..4b84f8f5 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Conversations/NewMessageModel.cs @@ -1,13 +1,8 @@ +using BotSharp.Abstraction.Conversations.Models; + namespace BotSharp.OpenAPI.ViewModels.Conversations; -public class NewMessageModel +public class NewMessageModel : IncomingMessageModel { - public string Text { get; set; } - public string ModelName { get; set; } = "gpt-3.5-turbo"; - public string Channel { get; set; } = "openapi"; - - /// - /// Conversation states from input - /// - public List States { get; set; } = new List(); + public override string Channel { get; set; } = "openapi"; } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index 19cd31db..819fb9dd 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -105,7 +105,9 @@ public class ChatCompletionProvider : IChatCompletion CurrentAgentId = agent.Id, FunctionName = message.FunctionCall.Name, FunctionArgs = message.FunctionCall.Arguments, - Channel = conversations.Last().Channel + Channel = conversations.Last().Channel, + Temperature = conversations.Last().Temperature, + SamplingFactor = conversations.Last().SamplingFactor }; // Somethings LLM will generate a function name with agent name. @@ -124,7 +126,9 @@ public class ChatCompletionProvider : IChatCompletion var msg = new RoleDialogModel(AgentRole.Assistant, message.Content) { CurrentAgentId= agent.Id, - Channel = conversations.Last().Channel + Channel = conversations.Last().Channel, + Temperature = conversations.Last().Temperature, + SamplingFactor = conversations.Last().SamplingFactor }; // Text response received @@ -226,8 +230,8 @@ public class ChatCompletionProvider : IChatCompletion } // https://community.openai.com/t/cheat-sheet-mastering-temperature-and-top-p-in-chatgpt-api-a-few-tips-and-tricks-on-controlling-the-creativity-deterministic-output-of-prompt-responses/172683 - chatCompletionsOptions.Temperature = 0.5f; - chatCompletionsOptions.NucleusSamplingFactor = 0.5f; + chatCompletionsOptions.Temperature = conversations.Last().Temperature; + chatCompletionsOptions.NucleusSamplingFactor = conversations.Last().SamplingFactor; var convSetting = _services.GetRequiredService(); if (convSetting.ShowVerboseLog) diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs index 9230bec3..0a8f3658 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs @@ -74,7 +74,10 @@ public class ChatbotUiController : ControllerBase, IApiAdapter .Where(x => x.Role == AgentRole.User) .Select(x => new RoleDialogModel(x.Role, x.Content) { - Channel = channel + Channel = channel, + ModelName = input.ModelName, + Temperature = input.Temperature, + SamplingFactor = input.SamplingFactor }).Last(); var conv = _services.GetRequiredService(); diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs index 76771738..ed88bc4b 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs @@ -1,23 +1,24 @@ +using BotSharp.Abstraction.Conversations.Models; using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; namespace BotSharp.Plugin.ChatbotUI.ViewModels; -public class OpenAiMessageInput +public class OpenAiMessageInput : IncomingMessageModel { - public string AgentId { get; set; } - public string ConversationId { get; set; } - public string Model { get; set; } = string.Empty; + public string AgentId { get; set; } = string.Empty; + public string ConversationId { get; set; } = string.Empty; + + [JsonPropertyName("model")] + public override string ModelName { get; set; } = string.Empty; + public List Messages { get; set; } = new List(); + [JsonPropertyName("max_tokens")] public int MaxTokens { get; set; } = 4000; + public bool Stream { get; set; } = true; - public float Temperature { get; set; } = 0.9f; - /// - /// Conversation states from input - /// - public List States { get; set; } = new List(); public override string ToString() {