diff --git a/Directory.Packages.props b/Directory.Packages.props index c840c156..d5721a14 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -46,7 +46,7 @@ - + diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Constants/LlmConstant.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Constants/LlmConstant.cs index 3919ca57..e45c8b15 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Constants/LlmConstant.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Constants/LlmConstant.cs @@ -3,4 +3,5 @@ namespace BotSharp.Abstraction.Agents.Constants; public static class LlmConstant { public const int DEFAULT_MAX_OUTPUT_TOKEN = 1024; + public const string DEFAULT_REASONING_EFFORT_LEVEL = "low"; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs index f1df3a01..75e3aa93 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -34,4 +34,11 @@ public class AgentLlmConfig [JsonPropertyName("max_output_tokens")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? MaxOutputTokens { get; set; } + + /// + /// Reasoning effort level + /// + [JsonPropertyName("reasoning_effort_level")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ReasoningEffortLevel { get; set; } } diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index 4543fe19..b6950e04 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -14,8 +14,7 @@ public class AgentController : ControllerBase public AgentController( IAgentService agentService, IUserIdentity user, - IServiceProvider services - ) + IServiceProvider services) { _agentService = agentService; _user = user; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs index b626d7da..63bc3b20 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentLlmConfigMongoElement.cs @@ -10,6 +10,7 @@ public class AgentLlmConfigMongoElement public bool IsInherit { get; set; } public int MaxRecursionDepth { get; set; } public int? MaxOutputTokens { get; set; } + public string? ReasoningEffortLevel { get; set; } public static AgentLlmConfigMongoElement? ToMongoElement(AgentLlmConfig? config) { @@ -22,6 +23,7 @@ public class AgentLlmConfigMongoElement IsInherit = config.IsInherit, MaxRecursionDepth = config.MaxRecursionDepth, MaxOutputTokens = config.MaxOutputTokens, + ReasoningEffortLevel = config.ReasoningEffortLevel }; } @@ -36,6 +38,7 @@ public class AgentLlmConfigMongoElement IsInherit = config.IsInherit, MaxRecursionDepth = config.MaxRecursionDepth, MaxOutputTokens = config.MaxOutputTokens, + ReasoningEffortLevel = config.ReasoningEffortLevel }; } } diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs index af7e7e0a..c9318d79 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs @@ -17,7 +17,12 @@ public class ChatCompletionProvider : IChatCompletion private readonly Dictionary _defaultTemperature = new() { - { "o4-mini", 1.0f } + { "o3", 1.0f }, + { "o3-mini", 1.0f }, + { "o4-mini", 1.0f }, + { "gpt-5", 1.0f }, + { "gpt-5-mini", 1.0f }, + { "gpt-5-nano", 1.0f } }; public virtual string Provider => "openai"; @@ -499,13 +504,42 @@ public class ChatCompletionProvider : IChatCompletion ? tokens : agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN; + var level = state.GetState("reasoning_effort_level") + .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel ?? string.Empty) + .IfNullOrEmptyAs(LlmConstant.DEFAULT_REASONING_EFFORT_LEVEL); + var reasoningEffortLevel = ParseReasoningEffortLevel(level); + return new ChatCompletionOptions() { Temperature = temperature, - MaxOutputTokenCount = maxTokens + MaxOutputTokenCount = maxTokens, + ReasoningEffortLevel = reasoningEffortLevel }; } + private ChatReasoningEffortLevel? ParseReasoningEffortLevel(string? level) + { + if (string.IsNullOrWhiteSpace(level) || !_defaultTemperature.ContainsKey(_model)) + { + return null; + } + + var effortLevel = ChatReasoningEffortLevel.Low; + switch (level.ToLower()) + { + case "medium": + effortLevel = ChatReasoningEffortLevel.Medium; + break; + case "high": + effortLevel = ChatReasoningEffortLevel.High; + break; + default: + break; + } + + return effortLevel; + } + public void SetModelName(string model) { _model = model;