From 7b05535089b181d8c85d93a00524c412716e4224 Mon Sep 17 00:00:00 2001 From: Vitali sharp8n Date: Thu, 17 Sep 2026 04:15:48 +0300 Subject: [PATCH] parameters --- .../Agents/Models/AgentLlmConfig.cs | 15 ++++++++++ .../Providers/Chat/ChatCompletionProvider.cs | 29 +++++++++++++------ .../Providers/Chat/ChatCompletionProvider.cs | 29 +++++++++++++------ .../Providers/Chat/ChatCompletionProvider.cs | 29 +++++++++++++------ 4 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs index 6ed259a3..be75a01e 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -35,6 +35,21 @@ public class AgentLlmConfig [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? MaxOutputTokens { get; set; } + /// + /// Sampling temperature override for this agent. null (the default) inherits the + /// conversation state / provider settings, so an unset field never changes global behavior. + /// + [JsonPropertyName("temperature")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public float? Temperature { get; set; } + + /// + /// Nucleus sampling (top-p) override for this agent. null inherits the defaults. + /// + [JsonPropertyName("top_p")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public float? TopP { get; set; } + /// /// Reasoning effort level /// diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs index dc9a0fbc..62d2d18c 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs @@ -565,23 +565,33 @@ public class ChatCompletionProvider : IChatCompletion var settingsService = _services.GetRequiredService(); var settings = settingsService.GetSetting(Provider, _model); + // Sampling: an explicit conversation state wins, then the agent's own override, then the + // model's configured reasoning defaults. Unset everywhere keeps the historical 0.0 fallback. + float? temperature = null; + if (state.ContainsState("temperature") && float.TryParse(state.GetState("temperature"), out var stateTemperature)) + temperature = stateTemperature; + temperature ??= agent?.LlmConfig?.Temperature; + temperature ??= settings?.Reasoning?.Temperature; + temperature ??= 0.2f; + + float? topP = null; + if (state.ContainsState("top_p") && float.TryParse(state.GetState("top_p"), out var stateTopP)) + topP = stateTopP; + topP ??= agent?.LlmConfig?.TopP; + // Reasoning effort ChatReasoningEffortLevel? reasoningEffortLevel = null; - float? temperature = float.Parse(state.GetState("temperature", "0.0")); - if (settings?.Reasoning != null) - { - temperature = settings.Reasoning.Temperature; - var level = state.GetState("reasoning_effort_level") - .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) - .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); - reasoningEffortLevel = ParseReasoningEffortLevel(level); - } + var level = state.GetState("reasoning_effort_level") + .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) + .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); + reasoningEffortLevel = ParseReasoningEffortLevel(level); // Web search ChatWebSearchOptions? webSearchOptions = null; if (settings?.WebSearch != null) { temperature = null; + topP = null; reasoningEffortLevel = null; webSearchOptions = new(); } @@ -593,6 +603,7 @@ public class ChatCompletionProvider : IChatCompletion return new ChatCompletionOptions() { Temperature = temperature, + TopP = topP, MaxOutputTokenCount = maxTokens, ReasoningEffortLevel = reasoningEffortLevel, WebSearchOptions = webSearchOptions diff --git a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs index eebc64d1..bb684dbc 100644 --- a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs @@ -691,23 +691,33 @@ public class ChatCompletionProvider : IChatCompletion var settingsService = _services.GetRequiredService(); var settings = settingsService.GetSetting(Provider, _model); + // Sampling: an explicit conversation state wins, then the agent's own override, then the + // model's configured reasoning defaults. Unset everywhere keeps the historical 0.0 fallback. + float? temperature = null; + if (state.ContainsState("temperature") && float.TryParse(state.GetState("temperature"), out var stateTemperature)) + temperature = stateTemperature; + temperature ??= agent?.LlmConfig?.Temperature; + temperature ??= settings?.Reasoning?.Temperature; + temperature ??= 0.2f; + + float? topP = null; + if (state.ContainsState("top_p") && float.TryParse(state.GetState("top_p"), out var stateTopP)) + topP = stateTopP; + topP ??= agent?.LlmConfig?.TopP; + // Reasoning effort ChatReasoningEffortLevel? reasoningEffortLevel = null; - float? temperature = float.Parse(state.GetState("temperature", "0.0")); - if (settings?.Reasoning != null) - { - temperature = settings.Reasoning.Temperature; - var level = state.GetState("reasoning_effort_level") - .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) - .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); - reasoningEffortLevel = ParseReasoningEffortLevel(level); - } + var level = state.GetState("reasoning_effort_level") + .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) + .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); + reasoningEffortLevel = ParseReasoningEffortLevel(level); // Web search ChatWebSearchOptions? webSearchOptions = null; if (settings?.WebSearch != null) { temperature = null; + topP = null; reasoningEffortLevel = null; webSearchOptions = new(); } @@ -719,6 +729,7 @@ public class ChatCompletionProvider : IChatCompletion return new ChatCompletionOptions() { Temperature = temperature, + TopP = topP, MaxOutputTokenCount = maxTokens, ReasoningEffortLevel = reasoningEffortLevel, WebSearchOptions = webSearchOptions diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs index 7ab149e2..cfe655c0 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs @@ -534,23 +534,33 @@ public class ChatCompletionProvider : IChatCompletion var settingsService = _services.GetRequiredService(); var settings = settingsService.GetSetting(Provider, _model); + // Sampling: an explicit conversation state wins, then the agent's own override, then the + // model's configured reasoning defaults. Unset everywhere keeps the historical 0.0 fallback. + float? temperature = null; + if (state.ContainsState("temperature") && float.TryParse(state.GetState("temperature"), out var stateTemperature)) + temperature = stateTemperature; + temperature ??= agent?.LlmConfig?.Temperature; + temperature ??= settings?.Reasoning?.Temperature; + temperature ??= 0.2f; + + float? topP = null; + if (state.ContainsState("top_p") && float.TryParse(state.GetState("top_p"), out var stateTopP)) + topP = stateTopP; + topP ??= agent?.LlmConfig?.TopP; + // Reasoning effort ChatReasoningEffortLevel? reasoningEffortLevel = null; - float? temperature = float.Parse(state.GetState("temperature", "0.0")); - if (settings?.Reasoning != null) - { - temperature = settings.Reasoning.Temperature; - var level = state.GetState("reasoning_effort_level") - .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) - .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); - reasoningEffortLevel = ParseReasoningEffortLevel(level); - } + var level = state.GetState("reasoning_effort_level") + .IfNullOrEmptyAs(agent?.LlmConfig?.ReasoningEffortLevel) + .IfNullOrEmptyAs(settings?.Reasoning?.EffortLevel); + reasoningEffortLevel = ParseReasoningEffortLevel(level); // Web search ChatWebSearchOptions? webSearchOptions = null; if (settings?.WebSearch != null) { temperature = null; + topP = null; reasoningEffortLevel = null; webSearchOptions = new(); } @@ -562,6 +572,7 @@ public class ChatCompletionProvider : IChatCompletion return new ChatCompletionOptions() { Temperature = temperature, + TopP = topP, MaxOutputTokenCount = maxTokens, ReasoningEffortLevel = reasoningEffortLevel, WebSearchOptions = webSearchOptions