From 90b62ffcb6557155f2924e26754f7ee8a2f29dc9 Mon Sep 17 00:00:00 2001 From: "nick.yi" Date: Thu, 17 Sep 2026 10:10:49 +0800 Subject: [PATCH 1/4] add ConversationStateServiceExtensions --- .../ConversationStateServiceExtensions.cs | 96 +++++++++++++++++++ .../Infrastructures/Enums/StateConst.cs | 1 + .../BotSharp.Core.Rules/Actions/ChatAction.cs | 3 +- .../BotSharp.Core.Rules/Engines/RuleEngine.cs | 3 +- .../Agents/Services/AgentService.LoadAgent.cs | 3 +- .../Agents/Services/AgentService.Rendering.cs | 3 +- .../Services/ConversationService.cs | 3 +- .../Demo/Functions/GetWeatherFn.cs | 3 +- .../Evaluations/Services/EvaluatingService.cs | 3 +- .../Routing/Reasoning/InstructExecutor.cs | 5 +- .../BotSharp.Core/Routing/RoutingService.cs | 5 +- .../Translation/TranslationResponseHook.cs | 2 +- .../Hooks/RateLimitConversationHook.cs | 3 +- .../Conversation/ConversationController.cs | 6 +- .../Instruct/InstructModeController.cs | 3 +- .../ChatbotUiController.cs | 3 +- .../Services/MessageHandleService.cs | 3 +- .../Services/TeamsMessageHandler.cs | 3 +- .../Controllers/TwilioInboundController.cs | 2 +- .../Functions/OutboundPhoneCallFn.cs | 2 +- .../Services/TwilioMessageQueueService.cs | 3 +- .../WeChatBackgroundService.cs | 3 +- 22 files changed, 137 insertions(+), 24 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationStateServiceExtensions.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationStateServiceExtensions.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationStateServiceExtensions.cs new file mode 100644 index 000000000..b3d47d9af --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationStateServiceExtensions.cs @@ -0,0 +1,96 @@ +using BotSharp.Abstraction.Conversations.Enums; +using BotSharp.Abstraction.Options; +using Newtonsoft.Json; +using System.Globalization; + +namespace BotSharp.Abstraction.Conversations; + +public static class ConversationStateServiceExtensions +{ + public static bool Equal(this IConversationStateService states, string name, string value) + { + return states.GetState(name) == value; + } + + public static bool NotEqual(this IConversationStateService states, string name, string value) + { + return !states.Equal(name, value); + } + + public static bool IsTrue(this IConversationStateService states, string name) + { + var value = states.GetState(name, "false"); + return bool.TryParse(value, out var result) ? result : false; + } + + public static bool IsFalse(this IConversationStateService states, string name) + { + return !states.IsTrue(name); + } + + public static bool IsNullOrEmpty(this IConversationStateService states, string name) + { + return string.IsNullOrEmpty(states.GetState(name)); + } + + public static bool IsNotNullOrEmpty(this IConversationStateService states, string name) + { + return !IsNullOrEmpty(states, name); + } + + /// + /// Get a state value and convert it to the target type. + /// Primitive/decimal/string/DateTime/enum are parsed with invariant culture, other types are deserialized from json. + /// + public static T GetState(this IConversationStateService states, string name, T defaultValue = default!, bool useNewtonsoftJson = true) + { + try + { + var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); + var isBasicType = targetType.IsPrimitive || targetType == typeof(decimal) || targetType == typeof(string); + var value = states.GetState(name, isBasicType ? defaultValue?.ToString() ?? "" : ""); + if (string.IsNullOrEmpty(value)) return defaultValue; + + if (isBasicType) + { + return (T)Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture); + } + else if (targetType == typeof(DateTime)) + { + return (T)(object)DateTime.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } + else if (targetType.IsEnum) + { + return (T)Enum.Parse(targetType, value, ignoreCase: true); + } + else + { + var result = useNewtonsoftJson + ? JsonConvert.DeserializeObject(value) + : System.Text.Json.JsonSerializer.Deserialize(value, BotSharpOptions.defaultJsonOptions); + return result is null ? defaultValue : result; + } + } + catch + { + // fall back to the default value when the state cannot be converted + } + + return defaultValue; + } + + public static bool IsPhoneChannel(this IConversationStateService states) + { + return states.GetState(StateConst.CHANNEL) == ConversationChannel.Phone; + } + + public static bool IsEmailChannel(this IConversationStateService states) + { + return states.GetState(StateConst.CHANNEL) == ConversationChannel.Email; + } + + public static bool IsOpenAPIChannel(this IConversationStateService states) + { + return states.GetState(StateConst.CHANNEL) == ConversationChannel.OpenAPI; + } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs index a4441acc6..72c0ff4b7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs @@ -13,6 +13,7 @@ public static class StateConst public const string LAZY_ROUTING_AGENT_ID = "lazy_routing_agent_id"; public const string LANGUAGE = "language"; + public const string CHANNEL = "channel"; /// /// Set from the incoming request: whether the caller wants the reply streamed back as it is generated. diff --git a/src/Infrastructure/BotSharp.Core.Rules/Actions/ChatAction.cs b/src/Infrastructure/BotSharp.Core.Rules/Actions/ChatAction.cs index a3d8b166d..ba817e2b5 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/Actions/ChatAction.cs +++ b/src/Infrastructure/BotSharp.Core.Rules/Actions/ChatAction.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Graph.Models; namespace BotSharp.Core.Rules.Actions; @@ -51,7 +52,7 @@ public async Task ExecuteAsync( var allStates = new List { - new("channel", channel) + new(StateConst.CHANNEL, channel) }; if (!context.Parameters.IsNullOrEmpty()) diff --git a/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs b/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs index 6d2083491..3a81b1221 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs +++ b/src/Infrastructure/BotSharp.Core.Rules/Engines/RuleEngine.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.MessageHub.Models; +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.MessageHub.Services; using BotSharp.Abstraction.Templating; @@ -188,7 +189,7 @@ private async Task SendMessageToAgent(IServiceProvider sp, Agent agent, var allStates = new List { - new("channel", trigger.Channel) + new(StateConst.CHANNEL, trigger.Channel) }; if (!states.IsNullOrEmpty()) diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs index 62647401b..da3d38ad2 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Hooks; +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Routing.Models; using System.Collections.Concurrent; @@ -91,7 +92,7 @@ private void OverrideInstructionByChannel(Agent agent) } var state = _services.GetRequiredService(); - var channel = state.GetState("channel"); + var channel = state.GetState(StateConst.CHANNEL); var found = instructions.FirstOrDefault(x => x.Channel.IsEqualTo(channel)); var defaultInstruction = instructions.FirstOrDefault(x => string.IsNullOrEmpty(x.Channel)); diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs index 7282a12b2..89706700b 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Instructs.Enums; +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.Templating; using Newtonsoft.Json.Linq; @@ -39,7 +40,7 @@ public bool RenderFunction(Agent agent, FunctionDef def, IDictionary(); - var channel = state.GetState("channel"); + var channel = state.GetState(StateConst.CHANNEL); if (!string.IsNullOrWhiteSpace(channel)) { isRender = isRender && channels.Contains(channel); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 9cffd3d9d..88551fe0b 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Models; +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Users.Models; using System.Threading.Tasks; @@ -208,7 +209,7 @@ public async Task GetConversationRecordOrCreateNew(string agentId) if (converation == null) { var state = _services.GetRequiredService(); - var channel = state.GetState("channel"); + var channel = state.GetState(StateConst.CHANNEL); var channelId = state.GetState("channel_id"); var userId = state.GetState("current_user_id"); var sess = new Conversation diff --git a/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs b/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs index 7677af206..85f125e52 100644 --- a/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs +++ b/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Functions; using BotSharp.Abstraction.Models; using BotSharp.Abstraction.SideCar; @@ -67,7 +68,7 @@ public async Task Execute(RoleDialogModel message) var text = $"I want to know fun events in {args?.City}"; var states = new List { - new() { Key = "channel", Value = "email" } + new() { Key = StateConst.CHANNEL, Value = "email" } }; var msg = await sidecar.SendMessage(message.CurrentAgentId, text, states: states); diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/Services/EvaluatingService.cs b/src/Infrastructure/BotSharp.Core/Evaluations/Services/EvaluatingService.cs index fbfb6ff24..24b7c305e 100644 --- a/src/Infrastructure/BotSharp.Core/Evaluations/Services/EvaluatingService.cs +++ b/src/Infrastructure/BotSharp.Core/Evaluations/Services/EvaluatingService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Evaluations; using BotSharp.Abstraction.Evaluations.Models; @@ -63,7 +64,7 @@ public async Task Execute(string task, EvaluationRequest request) response = await SendMessage(request.AgentId, conv.Id, question, states: new List { - new MessageState("channel", ConversationChannel.OpenAPI) + new MessageState(StateConst.CHANNEL, ConversationChannel.OpenAPI) }); dialogs.Add(new RoleDialogModel(AgentRole.Assistant, response.Content)); prompt += $"\r\n{AgentRole.Assistant}: {response.Content.Trim()}"; diff --git a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs index 268f1a3d8..440d482b7 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs @@ -66,11 +66,12 @@ await HookEmitter.Emit(_services, async hook => await hook.OnRouti else { var state = _services.GetRequiredService(); - var useStreamMsg = state.GetState(StateConst.USE_STREAM_MESSAGE); + var useStreamMsg = state.GetState(StateConst.USE_STREAM_MESSAGE); + var enLang = state.Equal(StateConst.LANGUAGE, LanguageType.ENGLISH); var options = new InvokeAgentOptions() { From = InvokeSource.Routing, - UseStream = bool.TryParse(useStreamMsg, out var useStream) && useStream + UseStream = useStreamMsg && enLang }; var ret = await routing.InvokeAgent(agentId, dialogs, options); } diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs index b6ac22cc3..9eacd923b 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs @@ -54,11 +54,12 @@ public async Task InstructDirect(Agent agent, RoleDialogModel m else { var state = _services.GetRequiredService(); - var useStreamMsg = state.GetState(StateConst.USE_STREAM_MESSAGE); + var useStreamMsg = state.GetState(StateConst.USE_STREAM_MESSAGE); + var enLang = state.Equal(StateConst.LANGUAGE, LanguageType.ENGLISH); var options = new InvokeAgentOptions() { From = InvokeSource.Routing, - UseStream = bool.TryParse(useStreamMsg, out var useStream) && useStream + UseStream = useStreamMsg && enLang }; var ret = await routing.InvokeAgent(agentId, dialogs, options); } diff --git a/src/Infrastructure/BotSharp.Core/Translation/TranslationResponseHook.cs b/src/Infrastructure/BotSharp.Core/Translation/TranslationResponseHook.cs index bf6bcbdf9..274707e91 100644 --- a/src/Infrastructure/BotSharp.Core/Translation/TranslationResponseHook.cs +++ b/src/Infrastructure/BotSharp.Core/Translation/TranslationResponseHook.cs @@ -30,7 +30,7 @@ public override async Task OnResponseGenerated(RoleDialogModel message) return; } - if (_states.GetState("channel") == ConversationChannel.Phone) + if (_states.IsPhoneChannel()) { return; } diff --git a/src/Infrastructure/BotSharp.Logger/Hooks/RateLimitConversationHook.cs b/src/Infrastructure/BotSharp.Logger/Hooks/RateLimitConversationHook.cs index 53cb91b42..a95f50f8f 100644 --- a/src/Infrastructure/BotSharp.Logger/Hooks/RateLimitConversationHook.cs +++ b/src/Infrastructure/BotSharp.Logger/Hooks/RateLimitConversationHook.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations.Enums; +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Users; @@ -30,7 +31,7 @@ public override async Task OnMessageReceived(RoleDialogModel message) var convId = states.GetConversationId(); var rateLimit = settings.RateLimit; - var channel = states.GetState("channel"); + var channel = states.GetState(StateConst.CHANNEL); // Check max input length var charCount = message.Content.Length; diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs index 425f60dc5..a935618bf 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs @@ -41,7 +41,7 @@ public ConversationController( public async Task NewConversation([FromRoute] string agentId, [FromBody] MessageConfig config) { var service = _services.GetRequiredService(); - var channel = config.States.FirstOrDefault(x => x.Key == "channel"); + var channel = config.States.FirstOrDefault(x => x.Key == StateConst.CHANNEL); var conv = new Conversation { AgentId = agentId, @@ -576,9 +576,9 @@ public ConverstionCancellationResponse StopStreaming([FromRoute] string conversa #region Private methods private void SetStates(IConversationService conv, NewMessageModel input) { - if (string.IsNullOrEmpty(conv.States.GetState("channel"))) + if (string.IsNullOrEmpty(conv.States.GetState(StateConst.CHANNEL))) { - conv.States.SetState("channel", input.Channel, source: StateSource.External); + conv.States.SetState(StateConst.CHANNEL, input.Channel, source: StateSource.External); } if (string.IsNullOrEmpty(conv.States.GetState("provider"))) { diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs index 9f5cb69b7..45089c7d3 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Instructs; using BotSharp.Abstraction.Instructs.Models; using BotSharp.Core.Infrastructures; @@ -157,7 +158,7 @@ private void SetStates(IConversationStateService state, InstructMessageModel inp .SetState("instruction", input.Instruction, source: StateSource.External) .SetState("input_text", input.Text, source: StateSource.External) .SetState("template_name", input.Template, source: StateSource.External) - .SetState("channel", input.Channel, source: StateSource.External) + .SetState(StateConst.CHANNEL, input.Channel, source: StateSource.External) .SetState("code_options", input.CodeOptions, source: StateSource.External) .SetState("file_options", input.FileOptions, source: StateSource.External) .SetState("file_count", input.Files?.Count, source: StateSource.External) diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs index b8885360b..0b0c9bf8a 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; @@ -77,7 +78,7 @@ public async Task SendMessage([FromBody] OpenAiMessageInput input) routing.Context.SetMessageId(input.ConversationId, message.MessageId); await conv.SetConversationId(input.ConversationId, input.States); - conv.States.SetState("channel", input.Channel) + conv.States.SetState(StateConst.CHANNEL, input.Channel) .SetState("provider", "azure-openai") .SetState("model", model) .SetState("temperature", input.Temperature) diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs index b367640bb..a8a3f6f4d 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/Services/MessageHandleService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Conversations.Models; @@ -61,7 +62,7 @@ await messenger.SendMessage(setting.ApiVersion, setting.PageId, routing.Context.SetMessageId(sender, inputMsg.MessageId); await conv.SetConversationId(sender, new List { - new MessageState("channel", ConversationChannel.Messenger) + new MessageState(StateConst.CHANNEL, ConversationChannel.Messenger) }); var replies = new List(); diff --git a/src/Plugins/BotSharp.Plugin.MicrosoftTeams/Services/TeamsMessageHandler.cs b/src/Plugins/BotSharp.Plugin.MicrosoftTeams/Services/TeamsMessageHandler.cs index 656423552..990f1e53f 100644 --- a/src/Plugins/BotSharp.Plugin.MicrosoftTeams/Services/TeamsMessageHandler.cs +++ b/src/Plugins/BotSharp.Plugin.MicrosoftTeams/Services/TeamsMessageHandler.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using Microsoft.Agents.Core.Models; namespace BotSharp.Plugin.MicrosoftTeams.Services; @@ -35,7 +36,7 @@ public async Task Handle(string userId, string agentId, string message, Func { - new MessageState("channel", ConversationChannel.Teams) + new MessageState(StateConst.CHANNEL, ConversationChannel.Teams) }); var replies = new List(); diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs index 5006a26f0..a63e776d7 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs @@ -171,7 +171,7 @@ protected Dictionary ParseStates(List states) var states = new List { - new("channel", ConversationChannel.Phone, isGlobal: true), + new(StateConst.CHANNEL, ConversationChannel.Phone, isGlobal: true), new("calling_phone", request.From, isGlobal: true), new("phone_direction", request.Direction, isGlobal: true), new("twilio_call_sid", request.CallSid, isGlobal: true), diff --git a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs index 75bde287e..6bb4537b3 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs @@ -206,7 +206,7 @@ private async Task ForkConversation( var subConvStates = new List { new(StateConst.ORIGIN_CONVERSATION_ID, originConversationId, isGlobal: true), - new("channel", "phone", isGlobal: true), + new(StateConst.CHANNEL, "phone", isGlobal: true), new("phone_from", call.From, isGlobal: true), new("phone_direction", call.Direction, isGlobal: true), new("phone_number", call.To, isGlobal: true), diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs index fbf6160dd..c7b7783b5 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioMessageQueueService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Files; using BotSharp.Abstraction.MessageHub.Models; using BotSharp.Abstraction.MessageHub.Services; @@ -140,7 +141,7 @@ private static async Task InitConversation(CallerMessage message, RoleDialogMode routing.Context.SetMessageId(message.ConversationId, inputMsg.MessageId); var states = new List { - new("channel", ConversationChannel.Phone), + new(StateConst.CHANNEL, ConversationChannel.Phone), new("channel_id", message.From), new("calling_phone", message.From) }; diff --git a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs index ee05f2b9d..326df8a14 100644 --- a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs +++ b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; @@ -59,7 +60,7 @@ private async Task HandleTextMessageAsync(string openid, string message) await conversationService.SetConversationId(latestConversationId, new List { - new MessageState("channel", "wechat") + new MessageState(StateConst.CHANNEL, "wechat") }); latestConversationId ??= (await conversationService.NewConversation(new Conversation() From 6dcb47146dfc5bc8c14f9e5d9090eefcf61c72dd Mon Sep 17 00:00:00 2001 From: "nick.yi" Date: Thu, 17 Sep 2026 10:37:02 +0800 Subject: [PATCH 2/4] optimize const --- .../Infrastructures/Enums/AudioStateConst.cs | 12 ++++++ .../Infrastructures/Enums/DataStateConst.cs | 12 ++++++ .../Infrastructures/Enums/ImageStateConst.cs | 14 +++++++ .../Infrastructures/Enums/LlmStateConst.cs | 22 ++++++++++ .../Infrastructures/Enums/TokenStateConst.cs | 11 +++++ .../Enums/WebSearchStateConst.cs | 14 +++++++ .../Conversations/Services/TokenStatistics.cs | 15 +++---- .../Infrastructures/CompletionProvider.cs | 15 +++---- .../Routing/Functions/RouteToAgentFn.cs | 4 +- .../RoutingService.HasMissingRequiredField.cs | 2 +- .../Functions/WebIntelligentSearchFn.cs | 5 ++- .../Conversation/ConversationController.cs | 18 ++++----- .../Conversation/TranslationController.cs | 3 +- .../Instruct/InstructModeController.cs | 18 ++++----- .../Providers/ChatCompletionProvider.cs | 40 ++++++++++++------- .../AudioCompletionProvider.SpeechToText.cs | 7 ++-- .../AudioCompletionProvider.TextToSpeech.cs | 3 +- .../Providers/Chat/ChatCompletionProvider.cs | 12 +++--- .../Image/ImageCompletionProvider.Edit.cs | 7 ++-- .../ImageCompletionProvider.Generation.cs | 11 ++--- .../ImageCompletionProvider.Variation.cs | 7 ++-- .../Providers/Text/TextCompletionProvider.cs | 3 +- .../ChatbotUiController.cs | 8 ++-- .../Providers/Chat/ChatCompletionProvider.cs | 12 +++--- .../Providers/Text/TextCompletionProvider.cs | 5 ++- .../Functions/ReadExcelFn.cs | 3 +- .../Services/MySqlService.cs | 3 +- .../Providers/Chat/ChatCompletionProvider.cs | 10 ++--- .../Providers/Chat/ChatCompletionProvider.cs | 10 ++--- .../Realtime/RealTimeCompletionProvider.cs | 8 ++-- .../Functions/ComposeImageFn.cs | 5 ++- .../Functions/EditImageFn.cs | 5 ++- .../Functions/GenerateImageFn.cs | 8 ++-- .../Providers/ChatCompletionProvider.cs | 5 ++- .../Providers/Chat/ChatCompletionProvider.cs | 12 +++--- .../Providers/Text/TextCompletionProvider.cs | 5 ++- .../Providers/ChatCompletionProvider.cs | 5 ++- ...osoftExtensionsAIChatCompletionProvider.cs | 5 ++- .../Providers/Chat/ChatCompletionProvider.cs | 5 ++- .../Providers/Audio/AudioSynthesisProvider.cs | 3 +- .../Audio/AudioTranscriptionProvider.cs | 7 ++-- .../Chat/ChatCompletionProvider.Chat.cs | 16 ++++---- .../Chat/ChatCompletionProvider.Response.cs | 22 +++++----- .../Image/ImageCompletionProvider.Edit.cs | 11 ++--- .../ImageCompletionProvider.Generation.cs | 13 +++--- .../ImageCompletionProvider.Variation.cs | 7 ++-- .../Realtime/RealTimeCompletionProvider.cs | 10 ++--- .../Providers/Text/TextCompletionProvider.cs | 3 +- .../Functions/SqlGenerationFn.cs | 9 +++-- .../Functions/SqlPrimaryStageFn.cs | 3 +- .../Functions/PrimaryStagePlanFn.cs | 3 +- .../TwoStaging/Functions/SummaryPlanFn.cs | 9 +++-- .../Functions/SqlValidateFn.cs | 3 +- .../Functions/VerifyDictionaryTerm.cs | 5 ++- .../Hooks/SqlDriverPlanningHook.cs | 3 +- .../UtilFunctions/VerifyDictionaryTerm.cs | 5 ++- 56 files changed, 316 insertions(+), 185 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/AudioStateConst.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/DataStateConst.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/ImageStateConst.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/LlmStateConst.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/TokenStateConst.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/WebSearchStateConst.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/AudioStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/AudioStateConst.cs new file mode 100644 index 000000000..6933c0e98 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/AudioStateConst.cs @@ -0,0 +1,12 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states for speech-to-text and text-to-speech requests. +/// +public static class AudioStateConst +{ + public const string AUDIO_TEMPERATURE = "audio_temperature"; + public const string AUDIO_RESPONSE_FORMAT = "audio_response_format"; + public const string AUDIO_GRANULARITY = "audio_granularity"; + public const string SPEECH_GENERATE_SPEED = "speech_generate_speed"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/DataStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/DataStateConst.cs new file mode 100644 index 000000000..4f8f0edca --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/DataStateConst.cs @@ -0,0 +1,12 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states shared by the data analytics plugins (Planner, SqlDriver, ExcelHandler). +/// +public static class DataStateConst +{ + public const string DICTIONARY_ITEMS = "dictionary_items"; + public const string TABLE_DDLS = "table_ddls"; + public const string TMP_TABLE = "tmp_table"; + public const string DATA_IMPORT_RESULT = "data_import_result"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/ImageStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/ImageStateConst.cs new file mode 100644 index 000000000..cb9e198c4 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/ImageStateConst.cs @@ -0,0 +1,14 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states for image generation, edit and variation requests. +/// +public static class ImageStateConst +{ + public const string IMAGE_COUNT = "image_count"; + public const string IMAGE_SIZE = "image_size"; + public const string IMAGE_QUALITY = "image_quality"; + public const string IMAGE_STYLE = "image_style"; + public const string IMAGE_BACKGROUND = "image_background"; + public const string IMAGE_RESPONSE_FORMAT = "image_response_format"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/LlmStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/LlmStateConst.cs new file mode 100644 index 000000000..6b9e439a6 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/LlmStateConst.cs @@ -0,0 +1,22 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states that tune how the LLM completion request is built. +/// +public static class LlmStateConst +{ + public const string PROVIDER = "provider"; + public const string MODEL = "model"; + public const string MODEL_ID = "model_id"; + public const string TEMPERATURE = "temperature"; + public const string MAX_TOKENS = "max_tokens"; + public const string SAMPLING_FACTOR = "sampling_factor"; + public const string RESPONSE_FORMAT = "response_format"; + public const string TOOL_CHOICE = "tool_choice"; + public const string REASONING_EFFORT_LEVEL = "reasoning_effort_level"; + public const string THINKING_TYPE = "thinking_type"; + public const string BUDGET_TOKENS = "budget_tokens"; + public const string USE_INTERLEAVED_THINKING = "use_interleaved_thinking"; + public const string SERVICE_TIER = "service_tier"; + public const string CHAT_IMAGE_DETAIL_LEVEL = "chat_image_detail_level"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/TokenStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/TokenStateConst.cs new file mode 100644 index 000000000..80e36f71e --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/TokenStateConst.cs @@ -0,0 +1,11 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states accumulating token usage and cost of the current conversation. +/// +public static class TokenStateConst +{ + public const string PROMPT_TOTAL = "prompt_total"; + public const string COMPLETION_TOTAL = "completion_total"; + public const string LLM_TOTAL_COST = "llm_total_cost"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/WebSearchStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/WebSearchStateConst.cs new file mode 100644 index 000000000..ba6952ed9 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/WebSearchStateConst.cs @@ -0,0 +1,14 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states for web search enabled completions. +/// +public static class WebSearchStateConst +{ + public const string ENABLE_WEB_SEARCH = "enable_web_search"; + public const string ENABLE_WEB_SEARCH_PREVIEW = "enable_web_search_preview"; + public const string WEB_SEARCH_CONTEXT_SIZE = "web_search_context_size"; + public const string WEB_SEARCH_USER_LOCATION = "web_search_user_location"; + public const string WEB_SEARCH_LLM_PROVIDER = "web_search_llm_provider"; + public const string WEB_SEARCH_LLM_MODEL = "web_search_llm_model"; +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs index 7385ea773..4920728d1 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.Infrastructures.Enums; using BotSharp.Abstraction.MLTasks; using System.Diagnostics; @@ -21,7 +22,7 @@ public float AccumulatedCost get { var stat = _services.GetRequiredService(); - return float.Parse(stat.GetState("llm_total_cost", "0")); + return stat.GetState(TokenStateConst.LLM_TOTAL_COST, 0f); } } @@ -80,15 +81,15 @@ public async Task AddToken(TokenStatsModel stats, RoleDialogModel message) // Accumulated Token var state = _services.GetRequiredService(); - var inputCount = int.Parse(state.GetState("prompt_total", "0")); - state.SetState("prompt_total", stats.TotalInputTokens + inputCount, isNeedVersion: false, source: StateSource.Application); - var outputCount = int.Parse(state.GetState("completion_total", "0")); - state.SetState("completion_total", stats.TotalOutputTokens + outputCount, isNeedVersion: false, source: StateSource.Application); + var inputCount = state.GetState(TokenStateConst.PROMPT_TOTAL, 0); + state.SetState(TokenStateConst.PROMPT_TOTAL, stats.TotalInputTokens + inputCount, isNeedVersion: false, source: StateSource.Application); + var outputCount = state.GetState(TokenStateConst.COMPLETION_TOTAL, 0); + state.SetState(TokenStateConst.COMPLETION_TOTAL, stats.TotalOutputTokens + outputCount, isNeedVersion: false, source: StateSource.Application); // Total cost - var total_cost = float.Parse(state.GetState("llm_total_cost", "0")); + var total_cost = state.GetState(TokenStateConst.LLM_TOTAL_COST, 0f); total_cost += deltaTotal; - state.SetState("llm_total_cost", total_cost, isNeedVersion: false, source: StateSource.Application); + state.SetState(TokenStateConst.LLM_TOTAL_COST, total_cost, isNeedVersion: false, source: StateSource.Application); // Save stats var metric = StatsMetric.AgentLlmCost; diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs index 8eac8adcd..6373d99c6 100644 --- a/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs +++ b/src/Infrastructure/BotSharp.Core/Infrastructures/CompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks.Settings; using BotSharp.Abstraction.Models; @@ -220,19 +221,19 @@ private static (string, string) GetProviderAndModel( if (string.IsNullOrEmpty(provider)) { provider = agentConfig?.Provider ?? agentSetting.LlmConfig?.Provider; - provider = state.GetState("provider", provider ?? "azure-openai"); + provider = state.GetState(LlmStateConst.PROVIDER, provider ?? "azure-openai"); } if (string.IsNullOrEmpty(model)) { model = agentConfig?.Model ?? agentSetting.LlmConfig?.Model; - if (state.ContainsState("model")) + if (state.ContainsState(LlmStateConst.MODEL)) { - model = state.GetState("model", model ?? "gpt-image-1-mini"); + model = state.GetState(LlmStateConst.MODEL, model ?? "gpt-image-1-mini"); } - else if (state.ContainsState("model_id") || !string.IsNullOrEmpty(modelId)) + else if (state.ContainsState(LlmStateConst.MODEL_ID) || !string.IsNullOrEmpty(modelId)) { - var modelIdentity = state.ContainsState("model_id") ? state.GetState("model_id") : modelId; + var modelIdentity = state.ContainsState(LlmStateConst.MODEL_ID) ? state.GetState(LlmStateConst.MODEL_ID) : modelId; var llmProviderService = services.GetRequiredService(); model = llmProviderService.GetProviderModel(provider, modelIdentity, multiModal: multiModal, @@ -241,8 +242,8 @@ private static (string, string) GetProviderAndModel( } } - state.SetState("provider", provider); - state.SetState("model", model); + state.SetState(LlmStateConst.PROVIDER, provider); + state.SetState(LlmStateConst.MODEL, model); return (provider, model); } } diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs index fad63ff7d..e81a00f91 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs @@ -28,10 +28,10 @@ public async Task Execute(RoleDialogModel message) if (!string.IsNullOrEmpty(args.OriginalAgent) && args.OriginalAgent.Length < 32) { // Correct user goal agent to keep orignal task - var goalAgentInState = states.GetState("user_goal_agent", string.Empty); + var goalAgentInState = states.GetState(StateConst.USER_GOAL_AGENT, string.Empty); if (args.OriginalAgent != goalAgentInState) { - states.SetState("user_goal_agent", args.OriginalAgent, isNeedVersion: true); + states.SetState(StateConst.USER_GOAL_AGENT, args.OriginalAgent, isNeedVersion: true); } var db = _services.GetRequiredService(); diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs index 10b70f25c..e9200aff3 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs @@ -48,7 +48,7 @@ public partial class RoutingService var states = _services.GetRequiredService(); foreach (var field in missingFields.ToList()) { - if (!string.IsNullOrEmpty(states.GetState(field))) + if (states.IsNotNullOrEmpty(field)) { var value = states.GetState(field); diff --git a/src/Infrastructure/BotSharp.Core/WebSearch/Functions/WebIntelligentSearchFn.cs b/src/Infrastructure/BotSharp.Core/WebSearch/Functions/WebIntelligentSearchFn.cs index be5fb3272..b8687ca87 100644 --- a/src/Infrastructure/BotSharp.Core/WebSearch/Functions/WebIntelligentSearchFn.cs +++ b/src/Infrastructure/BotSharp.Core/WebSearch/Functions/WebIntelligentSearchFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Functions; using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Models; @@ -74,8 +75,8 @@ private async Task GetChatCompletion(Agent agent, List var llmProviderService = _services.GetRequiredService(); var settingService = _services.GetRequiredService(); - var provider = state.GetState("web_search_llm_provider"); - var model = state.GetState("web_search_llm_model"); + var provider = state.GetState(WebSearchStateConst.WEB_SEARCH_LLM_PROVIDER); + var model = state.GetState(WebSearchStateConst.WEB_SEARCH_LLM_MODEL); if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs index a935618bf..137d5b871 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/ConversationController.cs @@ -576,25 +576,25 @@ public ConverstionCancellationResponse StopStreaming([FromRoute] string conversa #region Private methods private void SetStates(IConversationService conv, NewMessageModel input) { - if (string.IsNullOrEmpty(conv.States.GetState(StateConst.CHANNEL))) + if (conv.States.IsNullOrEmpty(StateConst.CHANNEL)) { conv.States.SetState(StateConst.CHANNEL, input.Channel, source: StateSource.External); } - if (string.IsNullOrEmpty(conv.States.GetState("provider"))) + if (conv.States.IsNullOrEmpty(LlmStateConst.PROVIDER)) { - conv.States.SetState("provider", input.Provider, source: StateSource.External); + conv.States.SetState(LlmStateConst.PROVIDER, input.Provider, source: StateSource.External); } - if (string.IsNullOrEmpty(conv.States.GetState("model"))) + if (conv.States.IsNullOrEmpty(LlmStateConst.MODEL)) { - conv.States.SetState("model", input.Model, source: StateSource.External); + conv.States.SetState(LlmStateConst.MODEL, input.Model, source: StateSource.External); } - if (string.IsNullOrEmpty(conv.States.GetState("temperature"))) + if (conv.States.IsNullOrEmpty(LlmStateConst.TEMPERATURE)) { - conv.States.SetState("temperature", input.Temperature, source: StateSource.External); + conv.States.SetState(LlmStateConst.TEMPERATURE, input.Temperature, source: StateSource.External); } - if (string.IsNullOrEmpty(conv.States.GetState("sampling_factor"))) + if (conv.States.IsNullOrEmpty(LlmStateConst.SAMPLING_FACTOR)) { - conv.States.SetState("sampling_factor", input.SamplingFactor, source: StateSource.External); + conv.States.SetState(LlmStateConst.SAMPLING_FACTOR, input.SamplingFactor, source: StateSource.External); } conv.States.SetState(StateConst.USE_STREAM_MESSAGE, input.IsStreamingMessage, source: StateSource.Application); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/TranslationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/TranslationController.cs index e2ea1903a..5d5ad75c9 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/TranslationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Conversation/TranslationController.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Options; using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Translation; @@ -26,7 +27,7 @@ public async Task Translate([FromBody] TranslationRequ var agent = await db.GetAgent(BuiltInAgentId.AIAssistant); var translator = _services.GetRequiredService(); var states = _services.GetRequiredService(); - states.SetState("max_tokens", "8192"); + states.SetState(LlmStateConst.MAX_TOKENS, "8192"); var text = await translator.Translate(agent, Guid.NewGuid().ToString(), model.Text.Split("\r\n"), language: model.ToLang); return new TranslationResponseModel { diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs index 45089c7d3..41a0632e5 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs @@ -80,9 +80,9 @@ public async Task TextCompletion([FromBody] IncomingInstructRequest inpu { var state = _services.GetRequiredService(); input.States.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); - state.SetState("provider", input.Provider ?? "azure-openai", source: StateSource.External) - .SetState("model", input.Model, source: StateSource.External) - .SetState("model_id", input.ModelId, source: StateSource.External); + state.SetState(LlmStateConst.PROVIDER, input.Provider ?? "azure-openai", source: StateSource.External) + .SetState(LlmStateConst.MODEL, input.Model, source: StateSource.External) + .SetState(LlmStateConst.MODEL_ID, input.ModelId, source: StateSource.External); var agentId = input.AgentId ?? Guid.Empty.ToString(); var textCompletion = CompletionProvider.GetTextCompletion(_services); @@ -108,9 +108,9 @@ public async Task ChatCompletion([FromBody] IncomingInstructRequest inpu { var state = _services.GetRequiredService(); input.States.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); - state.SetState("provider", input.Provider, source: StateSource.External) - .SetState("model", input.Model, source: StateSource.External) - .SetState("model_id", input.ModelId, source: StateSource.External); + state.SetState(LlmStateConst.PROVIDER, input.Provider, source: StateSource.External) + .SetState(LlmStateConst.MODEL, input.Model, source: StateSource.External) + .SetState(LlmStateConst.MODEL_ID, input.ModelId, source: StateSource.External); var agentId = input.AgentId ?? Guid.Empty.ToString(); var completion = CompletionProvider.GetChatCompletion(_services); @@ -152,9 +152,9 @@ private void SetStates(IConversationStateService state, InstructMessageModel inp { input.States.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); - state.SetState("provider", input.Provider, source: StateSource.External) - .SetState("model", input.Model, source: StateSource.External) - .SetState("model_id", input.ModelId, source: StateSource.External) + state.SetState(LlmStateConst.PROVIDER, input.Provider, source: StateSource.External) + .SetState(LlmStateConst.MODEL, input.Model, source: StateSource.External) + .SetState(LlmStateConst.MODEL_ID, input.ModelId, source: StateSource.External) .SetState("instruction", input.Instruction, source: StateSource.External) .SetState("input_text", input.Text, source: StateSource.External) .SetState("template_name", input.Template, source: StateSource.External) diff --git a/src/Plugins/BotSharp.Plugin.AnthropicAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AnthropicAI/Providers/ChatCompletionProvider.cs index 1b909a222..b9437120f 100644 --- a/src/Plugins/BotSharp.Plugin.AnthropicAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AnthropicAI/Providers/ChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using Anthropic.SDK.Common; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Core.Infrastructures.Streams; @@ -468,10 +469,9 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, } } - var temperature = decimal.Parse(_state.GetState("temperature", "0.0")); - var maxTokens = int.TryParse(_state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var temperature = _state.GetState(LlmStateConst.TEMPERATURE, 0.0m); + var maxTokens = _state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; parameters.Messages = messages; parameters.Tools = tools; @@ -498,7 +498,7 @@ public void SetModelName(string model) var thinkingType = LlmUtility.GetModelParameter( param, "ThinkingType", - _state.GetState("thinking_type")); + _state.GetState(LlmStateConst.THINKING_TYPE)); if (thinkingType.IsEqualTo("disabled")) { return null; @@ -514,20 +514,30 @@ public void SetModelName(string model) thinking.Type = ThinkingType.enabled; } - var bt = _state.GetState("budget_tokens"); - if (int.TryParse(bt, out var budgetTokens) - || (param.TryGetValue("BudgetTokens", out var value) - && int.TryParse(value.Default, out budgetTokens))) + var budgetTokens = _state.GetState(LlmStateConst.BUDGET_TOKENS); + if (budgetTokens == null + && param.TryGetValue("BudgetTokens", out var value) + && int.TryParse(value.Default, out var defaultBudgetTokens)) { - thinking.BudgetTokens = budgetTokens; + budgetTokens = defaultBudgetTokens; } - var enableInterleavedThinking = _state.GetState("use_interleaved_thinking"); - if (bool.TryParse(enableInterleavedThinking, out var useInterleavedThinking) - || (param.TryGetValue("UseInterleavedThinking", out value) - && bool.TryParse(value.Default, out useInterleavedThinking))) + if (budgetTokens.HasValue) { - thinking.UseInterleavedThinking = useInterleavedThinking; + thinking.BudgetTokens = budgetTokens.Value; + } + + var useInterleavedThinking = _state.GetState(LlmStateConst.USE_INTERLEAVED_THINKING); + if (useInterleavedThinking == null + && param.TryGetValue("UseInterleavedThinking", out value) + && bool.TryParse(value.Default, out var defaultInterleavedThinking)) + { + useInterleavedThinking = defaultInterleavedThinking; + } + + if (useInterleavedThinking.HasValue) + { + thinking.UseInterleavedThinking = useInterleavedThinking.Value; } return thinkingType.IsEqualTo("adaptive") diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs index 082daacf1..33143782a 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Audio; namespace BotSharp.Plugin.AzureOpenAI.Providers.Audio; @@ -17,9 +18,9 @@ public async Task TranscriptTextAsync(Stream audio, string audioFileName private AudioTranscriptionOptions PrepareTranscriptionOptions(string? text) { var state = _services.GetRequiredService(); - var format = GetTranscriptionResponseFormat(state.GetState("audio_response_format")); - var granularity = GetGranularity(state.GetState("audio_granularity")); - var temperature = GetTemperature(state.GetState("audio_temperature")); + var format = GetTranscriptionResponseFormat(state.GetState(AudioStateConst.AUDIO_RESPONSE_FORMAT)); + var granularity = GetGranularity(state.GetState(AudioStateConst.AUDIO_GRANULARITY)); + var temperature = GetTemperature(state.GetState(AudioStateConst.AUDIO_TEMPERATURE)); var options = new AudioTranscriptionOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs index 57c1f97e5..49a430f52 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Audio; namespace BotSharp.Plugin.AzureOpenAI.Providers.Audio; @@ -19,7 +20,7 @@ public async Task GenerateAudioFromTextAsync(string text, string? vo var state = _services.GetRequiredService(); var speechVoice = GetVoice(voice ?? "alloy"); var responseFormat = GetSpeechFormat(format ?? "mp3"); - var speed = GetSpeed(state.GetState("speech_generate_speed")); + var speed = GetSpeed(state.GetState(AudioStateConst.SPEECH_GENERATE_SPEED)); var options = new SpeechGenerationOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs index d9638e720..7ef687598 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Utilities; using BotSharp.Abstraction.Files.Utilities; @@ -463,7 +464,7 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, var imageDetailLevel = ChatImageDetailLevel.Auto; if (allowMultiModal) { - imageDetailLevel = ParseChatImageDetailLevel(state.GetState("chat_image_detail_level")); + imageDetailLevel = ParseChatImageDetailLevel(state.GetState(LlmStateConst.CHAT_IMAGE_DETAIL_LEVEL)); } foreach (var message in filteredMessages) @@ -610,11 +611,11 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) // Reasoning effort ChatReasoningEffortLevel? reasoningEffortLevel = null; - float? temperature = float.Parse(state.GetState("temperature", "0.0")); + float? temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); if (settings?.Reasoning != null) { temperature = settings.Reasoning.Temperature; - var level = state.GetState("reasoning_effort_level") + var level = state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL) .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); reasoningEffortLevel = ParseReasoningEffortLevel(level); @@ -629,9 +630,8 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) webSearchOptions = new(); } - var maxTokens = int.TryParse(state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; return new ChatCompletionOptions() { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs index 52e1a845a..4f44d9f23 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Images; namespace BotSharp.Plugin.AzureOpenAI.Providers.Image; @@ -52,9 +53,9 @@ public async Task GetImageEdits(Agent agent, RoleDialogModel me var prompt = message?.Payload ?? message?.Content ?? string.Empty; var state = _services.GetRequiredService(); - var size = GetImageSize(state.GetState("image_size")); - var format = GetImageFormat(state.GetState("image_response_format")); - var count = GetImageCount(state.GetState("image_count", "1")); + var size = GetImageSize(state.GetState(ImageStateConst.IMAGE_SIZE)); + var format = GetImageFormat(state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT)); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); var options = new ImageEditOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs index f5d8c1f92..450e2b014 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Images; namespace BotSharp.Plugin.AzureOpenAI.Providers.Image; @@ -30,11 +31,11 @@ public async Task GetImageGeneration(Agent agent, RoleDialogMod var prompt = message?.Payload ?? message?.Content ?? string.Empty; var state = _services.GetRequiredService(); - var size = GetImageSize(state.GetState("image_size")); - var quality = GetImageQuality(state.GetState("image_quality")); - var style = GetImageStyle(state.GetState("image_style")); - var format = GetImageFormat(state.GetState("image_response_format")); - var count = GetImageCount(state.GetState("image_count", "1")); + var size = GetImageSize(state.GetState(ImageStateConst.IMAGE_SIZE)); + var quality = GetImageQuality(state.GetState(ImageStateConst.IMAGE_QUALITY)); + var style = GetImageStyle(state.GetState(ImageStateConst.IMAGE_STYLE)); + var format = GetImageFormat(state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT)); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); var options = new ImageGenerationOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs index b2e4c5fe1..0cb165310 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Images; namespace BotSharp.Plugin.AzureOpenAI.Providers.Image; @@ -28,9 +29,9 @@ public async Task GetImageVariation(Agent agent, RoleDialogMode private (int, ImageVariationOptions) PrepareVariationOptions() { var state = _services.GetRequiredService(); - var size = GetImageSize(state.GetState("image_size")); - var format = GetImageFormat(state.GetState("image_response_format")); - var count = GetImageCount(state.GetState("image_count", "1")); + var size = GetImageSize(state.GetState(ImageStateConst.IMAGE_SIZE)); + var format = GetImageFormat(state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT)); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); var options = new ImageVariationOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Text/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Text/TextCompletionProvider.cs index 1bcabd20e..fa5f27541 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Text/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Text/TextCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Hooks; using BotSharp.Abstraction.MLTasks.Settings; using System.Net.Http; @@ -60,7 +61,7 @@ await hook.BeforeGenerating(agent, } var state = _services.GetRequiredService(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); var settingsService = _services.GetRequiredService(); var modelSetting = settingsService.GetSetting(Provider, _model); diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs index 0b0c9bf8a..a4a32e58e 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs @@ -79,10 +79,10 @@ public async Task SendMessage([FromBody] OpenAiMessageInput input) await conv.SetConversationId(input.ConversationId, input.States); conv.States.SetState(StateConst.CHANNEL, input.Channel) - .SetState("provider", "azure-openai") - .SetState("model", model) - .SetState("temperature", input.Temperature) - .SetState("sampling_factor", input.SamplingFactor); + .SetState(LlmStateConst.PROVIDER, "azure-openai") + .SetState(LlmStateConst.MODEL, model) + .SetState(LlmStateConst.TEMPERATURE, input.Temperature) + .SetState(LlmStateConst.SAMPLING_FACTOR, input.SamplingFactor); var result = await conv.SendMessage(input.AgentId, message, diff --git a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs index be2b11e51..8afe42097 100644 --- a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Utilities; using BotSharp.Abstraction.Files; @@ -428,7 +429,7 @@ public void SetModelName(string model) var imageDetailLevel = ChatImageDetailLevel.Auto; if (allowMultiModal) { - imageDetailLevel = ParseChatImageDetailLevel(state.GetState("chat_image_detail_level")); + imageDetailLevel = ParseChatImageDetailLevel(state.GetState(LlmStateConst.CHAT_IMAGE_DETAIL_LEVEL)); } foreach (var message in filteredMessages) @@ -574,11 +575,11 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) // Reasoning effort ChatReasoningEffortLevel? reasoningEffortLevel = null; - float? temperature = float.Parse(state.GetState("temperature", "0.0")); + float? temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); if (settings?.Reasoning != null) { temperature = settings.Reasoning.Temperature; - var level = state.GetState("reasoning_effort_level") + var level = state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL) .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); reasoningEffortLevel = ParseReasoningEffortLevel(level); @@ -593,9 +594,8 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) webSearchOptions = new(); } - var maxTokens = int.TryParse(state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; return new ChatCompletionOptions() { diff --git a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Text/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Text/TextCompletionProvider.cs index 28ad97f7b..e9f150f2a 100644 --- a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Text/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Text/TextCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Hooks; using Microsoft.Extensions.Logging; using OpenAI.Chat; @@ -89,8 +90,8 @@ public void SetModelName(string model) private ChatCompletionOptions PrepareOptions() { var state = _services.GetRequiredService(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); - var maxTokens = int.Parse(state.GetState("max_tokens", "1024")); + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS, 1024); return new ChatCompletionOptions { diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs index f0bd87755..079cab6db 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; @@ -53,7 +54,7 @@ public async Task Execute(RoleDialogModel message) var results = ImportDataFromDialogs(message, dialogs); message.Content = GenerateSqlExecutionSummary(results); - states.SetState("data_import_result", message.Content); + states.SetState(DataStateConst.DATA_IMPORT_RESULT, message.Content); dialogs.ForEach(x => x.Files = null); return true; } diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs index 5195a0c94..a76b45707 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using System.Data; using System.Text.RegularExpressions; using Newtonsoft.Json; @@ -53,7 +54,7 @@ public IEnumerable WriteExcelDataToDB(RoleDialogModel message, IW } string table = $"{_database}.{_tableName}"; - state.SetState("tmp_table", table); + state.SetState(DataStateConst.TMP_TABLE, table); var (isInsertSuccess, insertMessage) = SqlInsertDataFn(message, sheet); string exampleData = GetInsertExample(message, table); diff --git a/src/Plugins/BotSharp.Plugin.FloxiAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.FloxiAI/Providers/Chat/ChatCompletionProvider.cs index 56e2f64f0..05e153127 100644 --- a/src/Plugins/BotSharp.Plugin.FloxiAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.FloxiAI/Providers/Chat/ChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.MessageHub.Models; @@ -416,11 +417,10 @@ private static void Push( ["model"] = _model, ["messages"] = messages, ["stream"] = stream, - ["max_tokens"] = int.TryParse(state.GetState("max_tokens"), out var maxTokens) - ? maxTokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN, + ["max_tokens"] = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN, ["temperature"] = settings?.Reasoning?.Temperature - ?? (float.TryParse(state.GetState("temperature", "0.0"), out var temperature) ? temperature : 0f) + ?? state.GetState(LlmStateConst.TEMPERATURE, 0f) }; if (stream) @@ -450,7 +450,7 @@ private static void Push( private static bool IsThinkingEnabled(IConversationStateService state) { - return bool.TryParse(state.GetState(FloxiAiConstants.EnableThinkingState), out var enabled) && enabled; + return state.IsTrue(FloxiAiConstants.EnableThinkingState); } private static JsonObject TextMessage(string role, string content) diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs index d80e60f61..df4977bd8 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Files; using BotSharp.Abstraction.Files.Models; using BotSharp.Abstraction.Files.Utilities; @@ -601,10 +602,9 @@ public void SetModelName(string model) } var state = _services.GetRequiredService(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); - var maxTokens = int.TryParse(state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; var thinkingLevel = ParseThinking(settings?.Reasoning, agent); var request = new GenerateContentRequest @@ -694,7 +694,7 @@ private string GetPrompt(IEnumerable systemPrompts, IEnumerable #region Thinking level private ThinkingLevel? ParseThinking(ReasoningSetting? settings, Agent agent) { - var level = _state.GetState("reasoning_effort_level"); + var level = _state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL); if (string.IsNullOrEmpty(level) && _model == agent?.LlmConfig?.Model) { level = agent?.LlmConfig?.ReasoningEffortLevel; diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs index 62c4b3788..a21294996 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Hooks; using BotSharp.Abstraction.Realtime.Options; using BotSharp.Abstraction.Realtime.Sessions; @@ -594,10 +595,9 @@ await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, text) } var state = _services.GetRequiredService(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); - var maxTokens = int.TryParse(state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; var request = new GenerateContentRequest { diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ComposeImageFn.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ComposeImageFn.cs index 0097801c5..8bd12ec29 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ComposeImageFn.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ComposeImageFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Settings; namespace BotSharp.Plugin.ImageHandler.Functions; @@ -52,8 +53,8 @@ private void Init(RoleDialogModel message) private void SetImageOptions() { var state = _services.GetRequiredService(); - state.SetState("image_count", "1"); - state.SetState("image_response_format", "bytes"); + state.SetState(ImageStateConst.IMAGE_COUNT, "1"); + state.SetState(ImageStateConst.IMAGE_RESPONSE_FORMAT, "bytes"); } private async Task SelectImage(string? description) diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs index 59e7de286..bd7868ffc 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Settings; namespace BotSharp.Plugin.ImageHandler.Functions; @@ -52,8 +53,8 @@ private void Init(RoleDialogModel message) private void SetImageOptions() { var state = _services.GetRequiredService(); - state.SetState("image_count", "1"); - state.SetState("image_response_format", "bytes"); + state.SetState(ImageStateConst.IMAGE_COUNT, "1"); + state.SetState(ImageStateConst.IMAGE_RESPONSE_FORMAT, "bytes"); } private async Task SelectImage(string? description) diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs index 14a463d85..c24f28dd2 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Infrastructures.Enums; + namespace BotSharp.Plugin.ImageHandler.Functions; public class GenerateImageFn : IFunctionCallback @@ -47,9 +49,9 @@ private void Init(RoleDialogModel message) private void SetImageOptions() { var state = _services.GetRequiredService(); - state.SetState("image_count", "1"); - state.SetState("image_quality", "medium"); - state.SetState("image_response_format", "bytes"); + state.SetState(ImageStateConst.IMAGE_COUNT, "1"); + state.SetState(ImageStateConst.IMAGE_QUALITY, "medium"); + state.SetState(ImageStateConst.IMAGE_RESPONSE_FORMAT, "bytes"); } private async Task GetImageGeneration(Agent agent, RoleDialogModel message, string? description) diff --git a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs index 4c5cfc824..180375de8 100644 --- a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Hooks; @@ -122,7 +123,7 @@ public async Task GetChatCompletionsAsync(Agent agent, content += $"\r\n{AgentRole.Assistant}: "; var state = _services.GetRequiredService(); - var model = state.GetState("model", _settings.DefaultModel); + var model = state.GetState(LlmStateConst.MODEL, _settings.DefaultModel); var llama = _services.GetRequiredService(); llama.LoadModel(model); @@ -170,7 +171,7 @@ public async Task GetChatCompletionsAsync(Agent agent, public async Task GetChatCompletionsStreamingAsync(Agent agent, List conversations) { var state = _services.GetRequiredService(); - var model = state.GetState("model", "llama-2-7b-chat.Q8_0"); + var model = state.GetState(LlmStateConst.MODEL, "llama-2-7b-chat.Q8_0"); var llama = _services.GetRequiredService(); llama.LoadModel(model); diff --git a/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Chat/ChatCompletionProvider.cs index 0592db8db..3ea6b37ce 100644 --- a/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Chat/ChatCompletionProvider.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Utilities; using BotSharp.Abstraction.Files; @@ -428,7 +429,7 @@ public void SetModelName(string model) var imageDetailLevel = ChatImageDetailLevel.Auto; if (allowMultiModal) { - imageDetailLevel = ParseChatImageDetailLevel(state.GetState("chat_image_detail_level")); + imageDetailLevel = ParseChatImageDetailLevel(state.GetState(LlmStateConst.CHAT_IMAGE_DETAIL_LEVEL)); } foreach (var message in filteredMessages) @@ -574,11 +575,11 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) // Reasoning effort ChatReasoningEffortLevel? reasoningEffortLevel = null; - float? temperature = float.Parse(state.GetState("temperature", "0.0")); + float? temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); if (settings?.Reasoning != null) { temperature = settings.Reasoning.Temperature; - var level = state.GetState("reasoning_effort_level") + var level = state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL) .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); reasoningEffortLevel = ParseReasoningEffortLevel(level); @@ -593,9 +594,8 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) webSearchOptions = new(); } - var maxTokens = int.TryParse(state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; return new ChatCompletionOptions() { diff --git a/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Text/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Text/TextCompletionProvider.cs index 50ae2321a..827fb7547 100644 --- a/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Text/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.LiteLLM/Providers/Text/TextCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Hooks; using Microsoft.Extensions.Logging; using OpenAI.Chat; @@ -89,8 +90,8 @@ public void SetModelName(string model) private ChatCompletionOptions PrepareOptions() { var state = _services.GetRequiredService(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); - var maxTokens = int.Parse(state.GetState("max_tokens", "1024")); + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS, 1024); return new ChatCompletionOptions { diff --git a/src/Plugins/BotSharp.Plugin.MetaGLM/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.MetaGLM/Providers/ChatCompletionProvider.cs index 38c3b398d..a403955f6 100644 --- a/src/Plugins/BotSharp.Plugin.MetaGLM/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.MetaGLM/Providers/ChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Utilities; namespace BotSharp.Plugin.MetaGLM.Providers; @@ -149,8 +150,8 @@ private string PrepareOptions(Agent agent, List conversations, var prompt = GetPrompt(messages, toolcalls); //var state = _services.GetRequiredService(); - //var temperature = float.Parse(state.GetState("temperature", "0.0")); - //var samplingFactor = float.Parse(state.GetState("sampling_factor", "0.0")); + //var temperature = float.Parse(state.GetState(LlmStateConst.TEMPERATURE, "0.0")); + //var samplingFactor = float.Parse(state.GetState(LlmStateConst.SAMPLING_FACTOR, "0.0")); //dto.SetTemperature(temperature); return prompt; diff --git a/src/Plugins/BotSharp.Plugin.MicrosoftExtensionsAI/MicrosoftExtensionsAIChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.MicrosoftExtensionsAI/MicrosoftExtensionsAIChatCompletionProvider.cs index 888fe341d..d556b5039 100644 --- a/src/Plugins/BotSharp.Plugin.MicrosoftExtensionsAI/MicrosoftExtensionsAIChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.MicrosoftExtensionsAI/MicrosoftExtensionsAIChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; @@ -64,8 +65,8 @@ public async Task GetChatCompletions(Agent agent, List(); var options = new ChatOptions() { - Temperature = float.Parse(state.GetState("temperature", "0.0")), - MaxOutputTokens = int.Parse(state.GetState("max_tokens", "1024")) + Temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f), + MaxOutputTokens = state.GetState(LlmStateConst.MAX_TOKENS, 1024) }; // Configure messages diff --git a/src/Plugins/BotSharp.Plugin.MiniMaxAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.MiniMaxAI/Providers/Chat/ChatCompletionProvider.cs index 41bb743fc..c6407cf63 100644 --- a/src/Plugins/BotSharp.Plugin.MiniMaxAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.MiniMaxAI/Providers/Chat/ChatCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Chat; namespace BotSharp.Plugin.MiniMaxAI.Providers.Chat; @@ -25,7 +26,7 @@ protected override void ConfigureChatCompletionOptions( var thinkingType = LlmUtility.GetModelParameter( parameters, "ThinkingType", - _state.GetState("thinking_type")); + _state.GetState(LlmStateConst.THINKING_TYPE)); if (thinkingType is "adaptive" or "disabled") { var thinking = JsonSerializer.SerializeToUtf8Bytes(new { type = thinkingType }); @@ -36,7 +37,7 @@ protected override void ConfigureChatCompletionOptions( .Select(x => x.ServiceTier) .Distinct(StringComparer.OrdinalIgnoreCase); var serviceTier = LlmUtility.VerifyModelParameter( - _state.GetState("service_tier"), + _state.GetState(LlmStateConst.SERVICE_TIER), settings?.Cost?.DefaultServiceTier, serviceTiers); if (!string.IsNullOrWhiteSpace(serviceTier)) diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs index 6bf1f908f..71fa22586 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Audio; namespace BotSharp.Plugin.OpenAI.Providers.Audio; @@ -35,7 +36,7 @@ public async Task GenerateAudioAsync(string text, string? voice = "a var state = _services.GetRequiredService(); var speechVoice = GetVoice(voice ?? "alloy"); var responseFormat = GetSpeechFormat(format ?? "mp3"); - var speed = GetSpeed(state.GetState("speech_generate_speed")); + var speed = GetSpeed(state.GetState(AudioStateConst.SPEECH_GENERATE_SPEED)); var options = new SpeechGenerationOptions { diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs index 4649b7110..d37fa2586 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Audio; using System.Drawing; @@ -38,9 +39,9 @@ public async Task TranscriptTextAsync(Stream audio, string audioFileName private AudioTranscriptionOptions PrepareTranscriptionOptions(string? text, AudioTranscriptionSetting? settings) { var state = _services.GetRequiredService(); - var temperature = state.GetState("audio_temperature"); - var responseFormat = state.GetState("audio_response_format"); - var granularity = state.GetState("audio_granularity"); + var temperature = state.GetState(AudioStateConst.AUDIO_TEMPERATURE); + var responseFormat = state.GetState(AudioStateConst.AUDIO_RESPONSE_FORMAT); + var granularity = state.GetState(AudioStateConst.AUDIO_GRANULARITY); if (string.IsNullOrEmpty(temperature) && settings?.Temperature != null) { diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs index fa0c3a1bc..a0060e85e 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.MessageHub.Models; using BotSharp.Core.Infrastructures.Streams; using BotSharp.Core.MessageHub; @@ -441,7 +442,7 @@ private async Task InnerGetChatCompletionsStreamingAsync(Agent var imageDetailLevel = ChatImageDetailLevel.Auto; if (allowMultiModal) { - imageDetailLevel = ParseChatImageDetailLevel(_state.GetState("chat_image_detail_level")); + imageDetailLevel = ParseChatImageDetailLevel(_state.GetState(LlmStateConst.CHAT_IMAGE_DETAIL_LEVEL)); } foreach (var message in filteredMessages) @@ -610,7 +611,7 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) var settings = settingsService.GetSetting(Provider, _model); // Reasoning - float? temperature = float.Parse(_state.GetState("temperature", "0.0")); + float? temperature = _state.GetState(LlmStateConst.TEMPERATURE, 0.0f); var (reasoningTemp, reasoningEffortLevel) = ParseReasoning(settings?.Reasoning, agent); if (reasoningTemp.HasValue) { @@ -626,9 +627,8 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) webSearchOptions = new(); } - var maxTokens = int.TryParse(_state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var maxTokens = _state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; var options = new ChatCompletionOptions() { @@ -642,7 +642,7 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) if (webSearchOptions == null) { - var format = _state.GetState("response_format").IfNullOrEmptyAs(agent.LlmConfig?.ResponseFormat); + var format = _state.GetState(LlmStateConst.RESPONSE_FORMAT).IfNullOrEmptyAs(agent.LlmConfig?.ResponseFormat); options.ResponseFormat = GetChatResponseFormat(format); } @@ -670,7 +670,7 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) float? temperature = null; ChatReasoningEffortLevel? reasoningEffortLevel = null; - var level = _state.GetState("reasoning_effort_level"); + var level = _state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL); if (string.IsNullOrEmpty(level) && _model == agent?.LlmConfig?.Model) { @@ -744,7 +744,7 @@ private void AddChatToolChoice(ChatCompletionOptions options) } // Apply tool_choice only when tools are present; tool_choice is rejected by the API otherwise. - if (_state.GetState("tool_choice").IsEqualTo("required")) + if (_state.GetState(LlmStateConst.TOOL_CHOICE).IsEqualTo("required")) { options.ToolChoice = ChatToolChoice.CreateRequiredChoice(); } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs index 4136185c0..e3305ea91 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.MessageHub.Models; using BotSharp.Core.Infrastructures.Streams; using BotSharp.Core.MessageHub; @@ -438,9 +439,8 @@ private async Task InnerCreateResponseStreamingAsync(Agent agen var allowMultiModal = settings != null && settings.MultiModal; renderedInstructions = []; - var maxTokens = int.TryParse(_state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var maxTokens = _state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; var options = new CreateResponseOptions(_model, []) { @@ -513,7 +513,7 @@ private async Task InnerCreateResponseStreamingAsync(Agent agen var imageDetailLevel = ResponseImageDetailLevel.Auto; if (allowMultiModal) { - imageDetailLevel = ParseResponseImageDetailLevel(_state.GetState("chat_image_detail_level")); + imageDetailLevel = ParseResponseImageDetailLevel(_state.GetState(LlmStateConst.CHAT_IMAGE_DETAIL_LEVEL)); } foreach (var message in filteredMessages) @@ -605,7 +605,7 @@ private string GetResponseApiPrompt(CreateResponseOptions options) { ResponseReasoningEffortLevel? reasoningEffortLevel = null; - var level = _state.GetState("reasoning_effort_level"); + var level = _state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL); if (string.IsNullOrEmpty(level) && _model == agent?.LlmConfig?.Model) { level = agent?.LlmConfig?.ReasoningEffortLevel; @@ -739,12 +739,12 @@ private ResponseImageDetailLevel ParseResponseImageDetailLevel(string? level) #region Built-in tools private void AddBuiltInTools(IList tools, LlmModelSetting? modelSettings) { - if (bool.TryParse(_state.GetState("enable_web_search"), out var webSearchEnabled) && webSearchEnabled) + if (_state.IsTrue(WebSearchStateConst.ENABLE_WEB_SEARCH)) { var (location, contextSize) = ParseWebSearchContext(modelSettings?.WebSearch); tools.Add(ResponseTool.CreateWebSearchTool(userLocation: location, searchContextSize: contextSize)); } - else if (bool.TryParse(_state.GetState("enable_web_search_preview"), out var webSearchPreviewEnabled) && webSearchPreviewEnabled) + else if (_state.IsTrue(WebSearchStateConst.ENABLE_WEB_SEARCH_PREVIEW)) { var (location, contextSize) = ParseWebSearchContext(modelSettings?.WebSearch); tools.Add(ResponseTool.CreateWebSearchPreviewTool(userLocation: location, searchContextSize: contextSize)); @@ -756,7 +756,7 @@ private void AddBuiltInTools(IList tools, LlmModelSetting? modelSe WebSearchToolLocation? webSearchLocation = null; WebSearchToolContextSize? webSearchContextSize = null; - var contextSize = _state.GetState("web_search_context_size"); + var contextSize = _state.GetState(WebSearchStateConst.WEB_SEARCH_CONTEXT_SIZE); if (string.IsNullOrEmpty(contextSize) && settings?.Parameters != null && settings.Parameters.TryGetValue("SearchContextSize", out var settingValue) @@ -789,7 +789,7 @@ private void AddBuiltInTools(IList tools, LlmModelSetting? modelSe private WebSearchUserLocation? ResolveWebSearchUserLocation() { - var location = WebSearchUserLocation.FromJson(_state.GetState("web_search_user_location")); + var location = WebSearchUserLocation.FromJson(_state.GetState(WebSearchStateConst.WEB_SEARCH_USER_LOCATION)); if (location?.HasAnyValue == true) { return location; @@ -813,7 +813,7 @@ private void AddResponseToolChoice(CreateResponseOptions options) } // Apply tool_choice only when tools are present; tool_choice is rejected by the API otherwise. - if (_state.GetState("tool_choice").IsEqualTo("required")) + if (_state.GetState(LlmStateConst.TOOL_CHOICE).IsEqualTo("required")) { options.ToolChoice = ResponseToolChoice.CreateRequiredChoice(); } @@ -821,7 +821,7 @@ private void AddResponseToolChoice(CreateResponseOptions options) private void SetResponseFormat(CreateResponseOptions options, AgentLlmConfig? llmConfig) { - var format = _state.GetState("response_format").IfNullOrEmptyAs(llmConfig?.ResponseFormat); + var format = _state.GetState(LlmStateConst.RESPONSE_FORMAT).IfNullOrEmptyAs(llmConfig?.ResponseFormat); var responseFormat = GetResponseTextFormat(format); options.TextOptions = responseFormat != null ? new ResponseTextOptions { diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs index f6189d54d..a53a65fc6 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Images; namespace BotSharp.Plugin.OpenAI.Providers.Image; @@ -113,10 +114,10 @@ public async Task GetImageEdits(Agent agent, RoleDialogModel me var prompt = message?.Payload ?? message?.Content ?? string.Empty; var state = _services.GetRequiredService(); - var size = state.GetState("image_size"); - var quality = state.GetState("image_quality"); - var responseFormat = state.GetState("image_response_format"); - var background = state.GetState("image_background"); + var size = state.GetState(ImageStateConst.IMAGE_SIZE); + var quality = state.GetState(ImageStateConst.IMAGE_QUALITY); + var responseFormat = state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT); + var background = state.GetState(ImageStateConst.IMAGE_BACKGROUND); size = LlmUtility.GetModelParameter(settings?.Parameters, "Size", size); quality = LlmUtility.GetModelParameter(settings?.Parameters, "Quality", quality); @@ -141,7 +142,7 @@ public async Task GetImageEdits(Agent agent, RoleDialogModel me options.Background = GetImageBackground(background); } - var count = GetImageCount(state.GetState("image_count")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); return (prompt, count, options); } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs index cceaa3d1d..9fae687f4 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Images; namespace BotSharp.Plugin.OpenAI.Providers.Image; @@ -61,11 +62,11 @@ public async Task GetImageGeneration(Agent agent, RoleDialogMod var prompt = message?.Payload ?? message?.Content ?? string.Empty; var state = _services.GetRequiredService(); - var size = state.GetState("image_size"); - var quality = state.GetState("image_quality"); - var style = state.GetState("image_style"); - var responseFormat = state.GetState("image_response_format"); - var background = state.GetState("image_background"); + var size = state.GetState(ImageStateConst.IMAGE_SIZE); + var quality = state.GetState(ImageStateConst.IMAGE_QUALITY); + var style = state.GetState(ImageStateConst.IMAGE_STYLE); + var responseFormat = state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT); + var background = state.GetState(ImageStateConst.IMAGE_BACKGROUND); size = LlmUtility.GetModelParameter(settings?.Parameters, "Size", size); quality = LlmUtility.GetModelParameter(settings?.Parameters, "Quality", quality); @@ -95,7 +96,7 @@ public async Task GetImageGeneration(Agent agent, RoleDialogMod options.Background = GetImageBackground(background); } - var count = GetImageCount(state.GetState("image_count")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); return (prompt, count, options); } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs index 148ea95a3..0b5f296d7 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs @@ -1,4 +1,5 @@ #pragma warning disable OPENAI001 +using BotSharp.Abstraction.Infrastructures.Enums; using OpenAI.Images; namespace BotSharp.Plugin.OpenAI.Providers.Image; @@ -60,8 +61,8 @@ public async Task GetImageVariation(Agent agent, RoleDialogMode { var state = _services.GetRequiredService(); - var size = state.GetState("image_size"); - var responseFormat = state.GetState("image_response_format"); + var size = state.GetState(ImageStateConst.IMAGE_SIZE); + var responseFormat = state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT); size = LlmUtility.GetModelParameter(settings?.Parameters, "Size", size); responseFormat = LlmUtility.GetModelParameter(settings?.Parameters, "ResponseFormat", responseFormat); @@ -76,7 +77,7 @@ public async Task GetImageVariation(Agent agent, RoleDialogMode options.ResponseFormat = GetImageResponseFormat(responseFormat); } - var count = GetImageCount(state.GetState("image_count", "1")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); return (count, options); } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs index 40d9a0633..75acc51cb 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Realtime.Options; using BotSharp.Abstraction.Realtime.Settings; using BotSharp.Abstraction.Settings; @@ -576,10 +577,9 @@ private async Task OnUserAudioTranscriptionCompleted(RealtimeHu var messages = new List(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); - var maxTokens = int.TryParse(state.GetState("max_tokens"), out var tokens) - ? tokens - : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); + var maxTokens = state.GetState(LlmStateConst.MAX_TOKENS) + ?? agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; var options = new ChatCompletionOptions() { ToolChoice = ChatToolChoice.CreateAutoChoice(), @@ -770,7 +770,7 @@ private RealtimeAudioFormat ConvertAudioFormat(string format) private string? GetReasoningEffort(Agent agent) { var state = _services.GetRequiredService(); - var reasoningEffort = state.GetState("reasoning_effort_level"); + var reasoningEffort = state.GetState(LlmStateConst.REASONING_EFFORT_LEVEL); if (string.IsNullOrEmpty(reasoningEffort) && _model == agent?.LlmConfig?.Realtime?.Model) { diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Text/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Text/TextCompletionProvider.cs index 54db04a75..5532dd323 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Text/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Text/TextCompletionProvider.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Hooks; using System.Net.Http; using System.Net.Mime; @@ -49,7 +50,7 @@ await hook.BeforeGenerating(agent, } var state = _services.GetRequiredService(); - var temperature = float.Parse(state.GetState("temperature", "0.0")); + var temperature = state.GetState(LlmStateConst.TEMPERATURE, 0.0f); var settingsService = _services.GetRequiredService(); var modelSetting = settingsService.GetSetting(Provider, _model); diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs index 857f4c602..a1e6160da 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Plugin.Planner.SqlGeneration; using BotSharp.Plugin.Planner.TwoStaging; using BotSharp.Plugin.Planner.TwoStaging.Models; @@ -26,7 +27,7 @@ public async Task Execute(RoleDialogModel message) var agentService = _services.GetRequiredService(); var states = _services.GetRequiredService(); - states.SetState("max_tokens", "4096"); + states.SetState(LlmStateConst.MAX_TOKENS, "4096"); var currentAgent = await agentService.LoadAgent(message.CurrentAgentId); var taskRequirement = states.GetState("requirement_detail"); @@ -36,8 +37,8 @@ public async Task Execute(RoleDialogModel message) var ddlStatements = string.Empty; var domainKnowledge = states.GetState("planning_result"); domainKnowledge += "\r\n" + states.GetState("domain_knowledges"); - var dictionaryItems = states.GetState("dictionary_items"); - var excelImportResult = states.GetState("data_import_result"); + var dictionaryItems = states.GetState(DataStateConst.DICTIONARY_ITEMS); + var excelImportResult = states.GetState(DataStateConst.DATA_IMPORT_RESULT); foreach (var step in steps) { @@ -52,7 +53,7 @@ public async Task Execute(RoleDialogModel message) }); await fn.InvokeFunction("sql_table_definition", msgCopy); ddlStatements += "\r\n" + msgCopy.Content; - states.SetState("table_ddls", ddlStatements); + states.SetState(DataStateConst.TABLE_DDLS, ddlStatements); // Summarize and generate query var prompt = await GetSqlGenerationPrompt(msgCopy, taskRequirement, domainKnowledge, dictionaryItems, ddlStatements, excelImportResult); diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs index be6b8078b..0bd393f56 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Plugin.Planner.TwoStaging.Models; namespace BotSharp.Plugin.Planner.SqlGeneration.Functions; @@ -23,7 +24,7 @@ public async Task Execute(RoleDialogModel message) var agentService = _services.GetRequiredService(); var state = _services.GetRequiredService(); - state.SetState("max_tokens", "4096"); + state.SetState(LlmStateConst.MAX_TOKENS, "4096"); var task = JsonSerializer.Deserialize(message.FunctionArgs); var searchQuestions = new List(task.Questions); searchQuestions.AddRange(task.NormQuestions); diff --git a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs index 0d726b876..c79d45de1 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Plugin.Planner.TwoStaging.Models; namespace BotSharp.Plugin.Planner.TwoStaging.Functions; @@ -23,7 +24,7 @@ public async Task Execute(RoleDialogModel message) var agentService = _services.GetRequiredService(); var state = _services.GetRequiredService(); - state.SetState("max_tokens", "4096"); + state.SetState(LlmStateConst.MAX_TOKENS, "4096"); var task = JsonSerializer.Deserialize(message.FunctionArgs); var searchQuestions = new List(task.Questions); searchQuestions.AddRange(task.NormQuestions); diff --git a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs index f1f28c2b8..e10e008ad 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Plugin.Planner.TwoStaging.Models; namespace BotSharp.Plugin.Planner.TwoStaging.Functions; @@ -24,7 +25,7 @@ public async Task Execute(RoleDialogModel message) var agentService = _services.GetRequiredService(); var states = _services.GetRequiredService(); - states.SetState("max_tokens", "4096"); + states.SetState(LlmStateConst.MAX_TOKENS, "4096"); var currentAgent = await agentService.LoadAgent(message.CurrentAgentId); var taskRequirement = states.GetState("requirement_detail"); @@ -34,8 +35,8 @@ public async Task Execute(RoleDialogModel message) var ddlStatements = string.Empty; var domainKnowledge = states.GetState("planning_result"); domainKnowledge += "\r\n" + states.GetState("domain_knowledges"); - var dictionaryItems = states.GetState("dictionary_items"); - var excelImportResult = states.GetState("data_import_result"); + var dictionaryItems = states.GetState(DataStateConst.DICTIONARY_ITEMS); + var excelImportResult = states.GetState(DataStateConst.DATA_IMPORT_RESULT); foreach (var step in steps) { @@ -50,7 +51,7 @@ public async Task Execute(RoleDialogModel message) }); await fn.InvokeFunction("sql_table_definition", msgCopy); ddlStatements += "\r\n" + msgCopy.Content; - states.SetState("table_ddls", ddlStatements); + states.SetState(DataStateConst.TABLE_DDLS, ddlStatements); // Summarize and generate query var prompt = await GetSummaryPlanPrompt(msgCopy, taskRequirement, domainKnowledge, dictionaryItems, ddlStatements, excelImportResult); diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs index 23894bd17..44ef8ec50 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Instructs.Options; using BotSharp.Abstraction.Models; @@ -58,7 +59,7 @@ public async Task Execute(RoleDialogModel message) var states = _services.GetRequiredService(); var query = "Correct SQL Statement and keep the comments/explanations"; - var ddl = states.GetState("table_ddls"); + var ddl = states.GetState(DataStateConst.TABLE_DDLS); var correctedSql = await instructService.Instruct(query, new InstructOptions diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/VerifyDictionaryTerm.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/VerifyDictionaryTerm.cs index 44877071c..1a02cb28d 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/VerifyDictionaryTerm.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/VerifyDictionaryTerm.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Routing; using BotSharp.Core.Infrastructures; @@ -64,10 +65,10 @@ public async Task Execute(RoleDialogModel message) } var states = _services.GetRequiredService(); - var dictionaryItems = states.GetState("dictionary_items", ""); + var dictionaryItems = states.GetState(DataStateConst.DICTIONARY_ITEMS, ""); var newItem = BuildDictionaryItem(args.Table, args.Reason, message.Content); dictionaryItems += !string.IsNullOrWhiteSpace(newItem) ? $"\r\n{newItem}\r\n" : string.Empty; - states.SetState("dictionary_items", dictionaryItems); + states.SetState(DataStateConst.DICTIONARY_ITEMS, dictionaryItems); return true; } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs index bc8932f78..3233ca046 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.MLTasks; namespace BotSharp.Plugin.SqlDriver.Hooks; @@ -72,7 +73,7 @@ private RichContent BuildRunQueryButton(string conversationId, str string pattern = @"```sql\s*([\s\S]*?)\s*```"; var sql = Regex.Match(text, pattern).Groups[1].Value; var state = _services.GetRequiredService(); - var tmpTable = state.GetState("tmp_table"); + var tmpTable = state.GetState(DataStateConst.TMP_TABLE); var elements = new List() { }; elements.Add(new ElementButton diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/UtilFunctions/VerifyDictionaryTerm.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/UtilFunctions/VerifyDictionaryTerm.cs index 5fa48806c..ea56df35a 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/UtilFunctions/VerifyDictionaryTerm.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/UtilFunctions/VerifyDictionaryTerm.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Core.Infrastructures; using MySqlConnector; using static Dapper.SqlMapper; @@ -61,10 +62,10 @@ public async Task Execute(RoleDialogModel message) } var states = _services.GetRequiredService(); - var dictionaryItems = states.GetState("dictionary_items", ""); + var dictionaryItems = states.GetState(DataStateConst.DICTIONARY_ITEMS, ""); var newItem = BuildDictionaryItem(args.Table, args.Reason, message.Content); dictionaryItems += !string.IsNullOrWhiteSpace(newItem) ? $"\r\n{newItem}\r\n" : string.Empty; - states.SetState("dictionary_items", dictionaryItems); + states.SetState(DataStateConst.DICTIONARY_ITEMS, dictionaryItems); return true; } From ce516c7cdd8f74f936d5c1dcf484828cb6c9ed52 Mon Sep 17 00:00:00 2001 From: "nick.yi" Date: Thu, 17 Sep 2026 10:44:45 +0800 Subject: [PATCH 3/4] optimize const --- .../AudioCompletionProvider.SpeechToText.cs | 12 +---------- .../AudioCompletionProvider.TextToSpeech.cs | 12 +---------- .../Image/ImageCompletionProvider.Edit.cs | 2 +- .../ImageCompletionProvider.Generation.cs | 2 +- .../ImageCompletionProvider.Variation.cs | 2 +- .../Image/ImageCompletionProvider.cs | 7 ++----- .../Providers/Audio/AudioSynthesisProvider.cs | 12 +---------- .../Audio/AudioTranscriptionProvider.cs | 21 ++++--------------- .../Image/ImageCompletionProvider.Edit.cs | 2 +- .../ImageCompletionProvider.Generation.cs | 2 +- .../ImageCompletionProvider.Variation.cs | 2 +- .../Image/ImageCompletionProvider.cs | 7 ++----- 12 files changed, 17 insertions(+), 66 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs index 33143782a..3df79d086 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.SpeechToText.cs @@ -20,7 +20,7 @@ private AudioTranscriptionOptions PrepareTranscriptionOptions(string? text) var state = _services.GetRequiredService(); var format = GetTranscriptionResponseFormat(state.GetState(AudioStateConst.AUDIO_RESPONSE_FORMAT)); var granularity = GetGranularity(state.GetState(AudioStateConst.AUDIO_GRANULARITY)); - var temperature = GetTemperature(state.GetState(AudioStateConst.AUDIO_TEMPERATURE)); + var temperature = state.GetState(AudioStateConst.AUDIO_TEMPERATURE); var options = new AudioTranscriptionOptions { @@ -77,15 +77,5 @@ private AudioTimestampGranularities GetGranularity(string input) return granularity; } - - private float? GetTemperature(string input) - { - if (!float.TryParse(input, out var temperature)) - { - return null; - } - - return temperature; - } } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs index 49a430f52..f713b41ff 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Audio/AudioCompletionProvider.TextToSpeech.cs @@ -20,7 +20,7 @@ public async Task GenerateAudioFromTextAsync(string text, string? vo var state = _services.GetRequiredService(); var speechVoice = GetVoice(voice ?? "alloy"); var responseFormat = GetSpeechFormat(format ?? "mp3"); - var speed = GetSpeed(state.GetState(AudioStateConst.SPEECH_GENERATE_SPEED)); + var speed = state.GetState(AudioStateConst.SPEECH_GENERATE_SPEED); var options = new SpeechGenerationOptions { @@ -90,14 +90,4 @@ private GeneratedSpeechFormat GetSpeechFormat(string input) return format; } - - private float? GetSpeed(string input) - { - if (!float.TryParse(input, out var speed)) - { - return null; - } - - return speed; - } } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs index 4f44d9f23..ee384a05b 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Edit.cs @@ -55,7 +55,7 @@ public async Task GetImageEdits(Agent agent, RoleDialogModel me var state = _services.GetRequiredService(); var size = GetImageSize(state.GetState(ImageStateConst.IMAGE_SIZE)); var format = GetImageFormat(state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT)); - var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); var options = new ImageEditOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs index 450e2b014..4cb1e1b4d 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Generation.cs @@ -35,7 +35,7 @@ public async Task GetImageGeneration(Agent agent, RoleDialogMod var quality = GetImageQuality(state.GetState(ImageStateConst.IMAGE_QUALITY)); var style = GetImageStyle(state.GetState(ImageStateConst.IMAGE_STYLE)); var format = GetImageFormat(state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT)); - var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); var options = new ImageGenerationOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs index 0cb165310..86e024a27 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.Variation.cs @@ -31,7 +31,7 @@ public async Task GetImageVariation(Agent agent, RoleDialogMode var state = _services.GetRequiredService(); var size = GetImageSize(state.GetState(ImageStateConst.IMAGE_SIZE)); var format = GetImageFormat(state.GetState(ImageStateConst.IMAGE_RESPONSE_FORMAT)); - var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); var options = new ImageVariationOptions { diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.cs index 1c7f7e8da..033381f7a 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Image/ImageCompletionProvider.cs @@ -141,12 +141,9 @@ private GeneratedImageFormat GetImageFormat(string format) return retFormat; } - private int GetImageCount(string count) + private int GetImageCount(int? count) { - if (!int.TryParse(count, out var retCount)) - { - return DEFAULT_IMAGE_COUNT; - } + var retCount = count ?? DEFAULT_IMAGE_COUNT; if (retCount <= 0) { diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs index 71fa22586..10341abe3 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioSynthesisProvider.cs @@ -36,7 +36,7 @@ public async Task GenerateAudioAsync(string text, string? voice = "a var state = _services.GetRequiredService(); var speechVoice = GetVoice(voice ?? "alloy"); var responseFormat = GetSpeechFormat(format ?? "mp3"); - var speed = GetSpeed(state.GetState(AudioStateConst.SPEECH_GENERATE_SPEED)); + var speed = state.GetState(AudioStateConst.SPEECH_GENERATE_SPEED); var options = new SpeechGenerationOptions { @@ -104,14 +104,4 @@ private GeneratedSpeechFormat GetSpeechFormat(string input) return format; } - - private float? GetSpeed(string input) - { - if (!float.TryParse(input, out var speed)) - { - return null; - } - - return speed; - } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs index d37fa2586..41e471226 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Audio/AudioTranscriptionProvider.cs @@ -39,14 +39,11 @@ public async Task TranscriptTextAsync(Stream audio, string audioFileName private AudioTranscriptionOptions PrepareTranscriptionOptions(string? text, AudioTranscriptionSetting? settings) { var state = _services.GetRequiredService(); - var temperature = state.GetState(AudioStateConst.AUDIO_TEMPERATURE); + var temperature = state.GetState(AudioStateConst.AUDIO_TEMPERATURE); var responseFormat = state.GetState(AudioStateConst.AUDIO_RESPONSE_FORMAT); var granularity = state.GetState(AudioStateConst.AUDIO_GRANULARITY); - if (string.IsNullOrEmpty(temperature) && settings?.Temperature != null) - { - temperature = $"{settings.Temperature}"; - } + temperature ??= settings?.Temperature; responseFormat = LlmUtility.GetModelParameter(settings?.Parameters, "ResponseFormat", responseFormat); granularity = LlmUtility.GetModelParameter(settings?.Parameters, "Granularity", granularity); @@ -56,9 +53,9 @@ private AudioTranscriptionOptions PrepareTranscriptionOptions(string? text, Audi Prompt = text }; - if (!string.IsNullOrEmpty(temperature)) + if (temperature.HasValue) { - options.Temperature = GetTemperature(temperature); + options.Temperature = temperature; } if (!string.IsNullOrEmpty(responseFormat)) { @@ -122,14 +119,4 @@ private AudioTimestampGranularities GetGranularity(string input) return granularity; } - - private float? GetTemperature(string input) - { - if (!float.TryParse(input, out var temperature)) - { - return null; - } - - return temperature; - } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs index a53a65fc6..5ec80f4e4 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Edit.cs @@ -142,7 +142,7 @@ public async Task GetImageEdits(Agent agent, RoleDialogModel me options.Background = GetImageBackground(background); } - var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); return (prompt, count, options); } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs index 9fae687f4..e60e692e2 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Generation.cs @@ -96,7 +96,7 @@ public async Task GetImageGeneration(Agent agent, RoleDialogMod options.Background = GetImageBackground(background); } - var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); return (prompt, count, options); } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs index 0b5f296d7..818bbda2a 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.Variation.cs @@ -77,7 +77,7 @@ public async Task GetImageVariation(Agent agent, RoleDialogMode options.ResponseFormat = GetImageResponseFormat(responseFormat); } - var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT, "1")); + var count = GetImageCount(state.GetState(ImageStateConst.IMAGE_COUNT)); return (count, options); } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.cs index 884122208..9c037d002 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Image/ImageCompletionProvider.cs @@ -184,12 +184,9 @@ private GeneratedImageBackground GetImageBackground(string? background) return retBackground; } - private int GetImageCount(string count) + private int GetImageCount(int? count) { - if (!int.TryParse(count, out var retCount)) - { - return DEFAULT_IMAGE_COUNT; - } + var retCount = count ?? DEFAULT_IMAGE_COUNT; if (retCount <= 0) { From cf98bc31239985fe2e218b6e8dff93fe9f402834 Mon Sep 17 00:00:00 2001 From: "nick.yi" Date: Thu, 17 Sep 2026 11:35:28 +0800 Subject: [PATCH 4/4] optimize state Const --- .../Conversations/Enums/ConversationChannel.cs | 1 + .../Infrastructures/Enums/InstructStateConst.cs | 15 +++++++++++++++ .../BotSharp.Core.Rules/DemoRuleTrigger.cs | 4 +++- .../BotSharp.Core/Demo/Functions/GetWeatherFn.cs | 3 ++- .../Instruct/InstructModeController.cs | 14 +++++++------- .../Functions/OutboundPhoneCallFn.cs | 3 ++- .../WeChatBackgroundService.cs | 3 ++- 7 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/InstructStateConst.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs index 41e237898..462813d6e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ConversationChannel.cs @@ -8,6 +8,7 @@ public static class ConversationChannel public const string SMS = "sms"; public const string Messenger = "messenger"; public const string Teams = "teams"; + public const string WeChat = "wechat"; public const string Email = "email"; public const string Crontab = "crontab"; public const string Database = "database"; diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/InstructStateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/InstructStateConst.cs new file mode 100644 index 000000000..3c0b4999d --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/InstructStateConst.cs @@ -0,0 +1,15 @@ +namespace BotSharp.Abstraction.Infrastructures.Enums; + +/// +/// Conversation states carrying the input of an instruct mode request. +/// +public static class InstructStateConst +{ + public const string INSTRUCTION = "instruction"; + public const string INPUT_TEXT = "input_text"; + public const string TEMPLATE_NAME = "template_name"; + public const string CODE_OPTIONS = "code_options"; + public const string FILE_OPTIONS = "file_options"; + public const string FILE_COUNT = "file_count"; + public const string FILE_URLS = "file_urls"; +} diff --git a/src/Infrastructure/BotSharp.Core.Rules/DemoRuleTrigger.cs b/src/Infrastructure/BotSharp.Core.Rules/DemoRuleTrigger.cs index 70a9eac22..3db0fed5a 100644 --- a/src/Infrastructure/BotSharp.Core.Rules/DemoRuleTrigger.cs +++ b/src/Infrastructure/BotSharp.Core.Rules/DemoRuleTrigger.cs @@ -1,8 +1,10 @@ +using BotSharp.Abstraction.Conversations.Enums; + namespace BotSharp.Core.Rules; public class DemoRuleTrigger : IRuleTrigger { - public string Channel => "crontab"; + public string Channel => ConversationChannel.Crontab; public string Name => nameof(DemoRuleTrigger); public string EntityType { get; set; } = "DemoType"; diff --git a/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs b/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs index 85f125e52..95ed84594 100644 --- a/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs +++ b/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Functions; using BotSharp.Abstraction.Models; @@ -68,7 +69,7 @@ public async Task Execute(RoleDialogModel message) var text = $"I want to know fun events in {args?.City}"; var states = new List { - new() { Key = StateConst.CHANNEL, Value = "email" } + new() { Key = StateConst.CHANNEL, Value = ConversationChannel.Email } }; var msg = await sidecar.SendMessage(message.CurrentAgentId, text, states: states); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs index 41a0632e5..b8407601e 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/Instruct/InstructModeController.cs @@ -155,14 +155,14 @@ private void SetStates(IConversationStateService state, InstructMessageModel inp state.SetState(LlmStateConst.PROVIDER, input.Provider, source: StateSource.External) .SetState(LlmStateConst.MODEL, input.Model, source: StateSource.External) .SetState(LlmStateConst.MODEL_ID, input.ModelId, source: StateSource.External) - .SetState("instruction", input.Instruction, source: StateSource.External) - .SetState("input_text", input.Text, source: StateSource.External) - .SetState("template_name", input.Template, source: StateSource.External) + .SetState(InstructStateConst.INSTRUCTION, input.Instruction, source: StateSource.External) + .SetState(InstructStateConst.INPUT_TEXT, input.Text, source: StateSource.External) + .SetState(InstructStateConst.TEMPLATE_NAME, input.Template, source: StateSource.External) .SetState(StateConst.CHANNEL, input.Channel, source: StateSource.External) - .SetState("code_options", input.CodeOptions, source: StateSource.External) - .SetState("file_options", input.FileOptions, source: StateSource.External) - .SetState("file_count", input.Files?.Count, source: StateSource.External) - .SetState("file_urls", input.Files?.Select(p => p.ToString()), source: StateSource.External); + .SetState(InstructStateConst.CODE_OPTIONS, input.CodeOptions, source: StateSource.External) + .SetState(InstructStateConst.FILE_OPTIONS, input.FileOptions, source: StateSource.External) + .SetState(InstructStateConst.FILE_COUNT, input.Files?.Count, source: StateSource.External) + .SetState(InstructStateConst.FILE_URLS, input.Files?.Select(p => p.ToString()), source: StateSource.External); } private async Task OnChunkReceived(HttpResponse response, InstructResult result) diff --git a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs index 6bb4537b3..c0003b785 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/OutboundPhoneCallFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Files; using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Options; @@ -206,7 +207,7 @@ private async Task ForkConversation( var subConvStates = new List { new(StateConst.ORIGIN_CONVERSATION_ID, originConversationId, isGlobal: true), - new(StateConst.CHANNEL, "phone", isGlobal: true), + new(StateConst.CHANNEL, ConversationChannel.Phone, isGlobal: true), new("phone_from", call.From, isGlobal: true), new("phone_direction", call.Direction, isGlobal: true), new("phone_number", call.To, isGlobal: true), diff --git a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs index 326df8a14..5ff2c9eef 100644 --- a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs +++ b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Infrastructures.Enums; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations; @@ -60,7 +61,7 @@ private async Task HandleTextMessageAsync(string openid, string message) await conversationService.SetConversationId(latestConversationId, new List { - new MessageState(StateConst.CHANNEL, "wechat") + new MessageState(StateConst.CHANNEL, ConversationChannel.WeChat) }); latestConversationId ??= (await conversationService.NewConversation(new Conversation()