diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs index 0dff7d62e..b069de92b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -4,13 +4,13 @@ public class AgentLlmConfig { public AgentLlmConfig() { } - public AgentLlmConfig(AgentTemplateConfig templateConfig) + public AgentLlmConfig(AgentTemplateLlmConfig templateLlmConfig) { - Provider = templateConfig.LlmConfig?.Provider; - Model = templateConfig.LlmConfig?.Model; - MaxOutputTokens = templateConfig.LlmConfig?.MaxOutputTokens; - ReasoningEffortLevel = templateConfig.LlmConfig?.ReasoningEffortLevel; - ResponseFormat = templateConfig.ResponseFormat; + Provider = templateLlmConfig?.Provider; + Model = templateLlmConfig?.Model; + MaxOutputTokens = templateLlmConfig?.MaxOutputTokens; + ReasoningEffortLevel = templateLlmConfig?.ReasoningEffortLevel; + ResponseFormat = templateLlmConfig?.ResponseFormat; } /// @@ -53,6 +53,13 @@ public AgentLlmConfig(AgentTemplateConfig templateConfig) [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ReasoningEffortLevel { get; set; } + /// + /// Response format: json, xml, markdown, yaml, etc. + /// + [JsonPropertyName("response_format")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ResponseFormat { get; set; } + /// /// Image composition config /// @@ -73,13 +80,6 @@ public AgentLlmConfig(AgentTemplateConfig templateConfig) [JsonPropertyName("realtime")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public LlmRealtimeConfig? Realtime { get; set; } - - /// - /// Response format: json, xml, markdown, yaml, etc. - /// - [JsonPropertyName("response_format")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? ResponseFormat { get; set; } } public class LlmImageCompositionConfig : LlmProviderModel diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentTemplate.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentTemplate.cs index a39be67ab..5315adf44 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentTemplate.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentTemplate.cs @@ -24,13 +24,6 @@ public class AgentTemplateConfig { public string Name { get; set; } - /// - /// Response format: json, xml, markdown, yaml, etc. - /// - [JsonPropertyName("response_format")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? ResponseFormat { get; set; } - [JsonPropertyName("llm_config")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public AgentTemplateLlmConfig? LlmConfig { get; set; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs b/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs index 3d7df31f1..93a3aedb6 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs @@ -15,6 +15,13 @@ public class LlmConfigBase : LlmProviderModel [JsonPropertyName("reasoning_effort_level")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ReasoningEffortLevel { get; set; } + + /// + /// Response format: json, xml, markdown, yaml, etc. + /// + [JsonPropertyName("response_format")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ResponseFormat { get; set; } } public class LlmProviderModel diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs index 2c433b04b..8b73e2424 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs @@ -112,7 +112,6 @@ private List GetTemplatesFromFile(string fileDir) var config = configs.FirstOrDefault(x => x.Name.IsEqualTo(name)); if (config != null) { - template.ResponseFormat = config.ResponseFormat; template.LlmConfig = config.LlmConfig; } templates.Add(template); diff --git a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs index 51e3b750a..32d094089 100644 --- a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs +++ b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs @@ -248,10 +248,10 @@ private async Task RunLlm( if (!string.IsNullOrEmpty(templateName)) { prompt = agentService.RenderTemplate(agent, templateName); - var template = agent.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(templateName)); - if (template?.LlmConfig?.IsValid == true) + var templateLlmConfig = agent.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(templateName))?.LlmConfig; + if (templateLlmConfig?.IsValid == true) { - llmConfig = new AgentLlmConfig(template); + llmConfig = new AgentLlmConfig(templateLlmConfig); } } else diff --git a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Instruct.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Instruct.cs index 547a411be..07cea0933 100644 --- a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Instruct.cs +++ b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Instruct.cs @@ -68,9 +68,10 @@ private async Task BuildInnerAgent(InstructOptions? options) { var template = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(options.TemplateName)); instruction = BuildInstruction(template?.Content ?? string.Empty, options?.Data ?? []); - if (template?.LlmConfig?.IsValid == true) + var templateLlmConfig = template?.LlmConfig; + if (templateLlmConfig?.IsValid == true) { - llmConfig = new AgentLlmConfig(template); + llmConfig = new AgentLlmConfig(templateLlmConfig); } } } diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index 479640a3f..745121397 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -440,7 +440,6 @@ private async Task UpdateAgentTemplates(string agentId, List temp var configs = templates.Select(t => new AgentTemplateConfig { Name = t.Name, - ResponseFormat = t.ResponseFormat, LlmConfig = t.LlmConfig }).ToList(); @@ -765,7 +764,6 @@ public async Task GetAgentTemplate(string agentId, string templateName) var found = configs?.FirstOrDefault(x => x.Name.IsEqualTo(templateName)); if (found != null) { - template.ResponseFormat = found.ResponseFormat; template.LlmConfig = found.LlmConfig; } } @@ -807,7 +805,6 @@ public async Task PatchAgentTemplate(string agentId, AgentTemplate templat var existingConfig = configs.FirstOrDefault(x => x.Name.IsEqualTo(template.Name)); if (existingConfig != null) { - existingConfig.ResponseFormat = template.ResponseFormat; existingConfig.LlmConfig = template.LlmConfig; } else @@ -815,7 +812,6 @@ public async Task PatchAgentTemplate(string agentId, AgentTemplate templat configs.Add(new AgentTemplateConfig { Name = template.Name, - ResponseFormat = template.ResponseFormat, LlmConfig = template.LlmConfig }); } diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs index 2b98fca40..3725c1648 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs @@ -406,7 +406,6 @@ private List FetchTemplates(string fileDir) var config = configs.FirstOrDefault(x => x.Name.IsEqualTo(name)); if (config != null) { - template.ResponseFormat = config.ResponseFormat; template.LlmConfig = config.LlmConfig; } templates.Add(template); diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateLlmConfigMongoModel.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateLlmConfigMongoModel.cs index 6ca7c48f1..ac922323d 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateLlmConfigMongoModel.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateLlmConfigMongoModel.cs @@ -8,6 +8,7 @@ public class AgentTemplateLlmConfigMongoModel public string? Model { get; set; } public int? MaxOutputTokens { get; set; } public string? ReasoningEffortLevel { get; set; } + public string? ResponseFormat { get; set; } public static AgentTemplateLlmConfigMongoModel? ToMongoModel(AgentTemplateLlmConfig? config) { @@ -21,7 +22,8 @@ public class AgentTemplateLlmConfigMongoModel Provider = config.Provider, Model = config.Model, MaxOutputTokens = config.MaxOutputTokens, - ReasoningEffortLevel = config.ReasoningEffortLevel + ReasoningEffortLevel = config.ReasoningEffortLevel, + ResponseFormat = config.ResponseFormat }; } @@ -37,7 +39,8 @@ public class AgentTemplateLlmConfigMongoModel Provider = config.Provider, Model = config.Model, MaxOutputTokens = config.MaxOutputTokens, - ReasoningEffortLevel = config.ReasoningEffortLevel + ReasoningEffortLevel = config.ReasoningEffortLevel, + ResponseFormat = config.ResponseFormat }; } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs index ca95e6185..005fe624e 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentTemplateMongoElement.cs @@ -7,7 +7,6 @@ public class AgentTemplateMongoElement { public string Name { get; set; } = default!; public string Content { get; set; } = string.Empty; - public string? ResponseFormat { get; set; } public AgentTemplateLlmConfigMongoModel? LlmConfig { get; set; } public static AgentTemplateMongoElement ToMongoElement(AgentTemplate template) @@ -16,7 +15,6 @@ public static AgentTemplateMongoElement ToMongoElement(AgentTemplate template) { Name = template.Name, Content = template.Content, - ResponseFormat = template.ResponseFormat, LlmConfig = AgentTemplateLlmConfigMongoModel.ToMongoModel(template.LlmConfig) }; } @@ -27,7 +25,6 @@ public static AgentTemplate ToDomainElement(AgentTemplateMongoElement mongoTempl { Name = mongoTemplate.Name, Content = mongoTemplate.Content, - ResponseFormat = mongoTemplate.ResponseFormat, LlmConfig = AgentTemplateLlmConfigMongoModel.ToDomainModel(mongoTemplate.LlmConfig) }; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs index 74f4556e7..52f7484f4 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -592,7 +592,6 @@ public async Task PatchAgentTemplate(string agentId, AgentTemplate templat } foundTemplate.Content = template.Content; - foundTemplate.ResponseFormat = template.ResponseFormat; foundTemplate.LlmConfig = AgentTemplateLlmConfigMongoModel.ToMongoModel(template.LlmConfig); var update = Builders.Update.Set(x => x.Templates, agent.Templates); await _dc.Agents.UpdateOneAsync(filter, update); 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 d4217a65e..55dc8eeb6 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Chat.cs @@ -628,7 +628,8 @@ private ChatCompletionOptions InitChatCompletionOption(Agent agent) if (webSearchOptions == null) { - options.ResponseFormat = GetChatResponseFormat(agent.LlmConfig?.ResponseFormat); + var format = _state.GetState("response_format").IfNullOrEmptyAs(agent.LlmConfig?.ResponseFormat); + options.ResponseFormat = GetChatResponseFormat(format); } return options; 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 3edb9be33..678010118 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.Response.cs @@ -435,6 +435,7 @@ private async Task InnerCreateResponseStreamingAsync(Agent agen MaxOutputTokenCount = maxTokens, }; + // Reasoning level var reasoningEffortLevel = ParseResponseReasoning(settings?.Reasoning, agent); if (reasoningEffortLevel.HasValue) { @@ -451,14 +452,7 @@ private async Task InnerCreateResponseStreamingAsync(Agent agen } // Response format - var textFormat = GetResponseTextFormat(agent.LlmConfig?.ResponseFormat); - if (textFormat != null) - { - options.TextOptions = new ResponseTextOptions - { - TextFormat = textFormat - }; - } + SetResponseFormat(options, agent.LlmConfig); // Prepare instruction and functions var renderData = agentService.CollectRenderData(agent); @@ -817,5 +811,15 @@ private void AddResponseToolChoice(CreateResponseOptions options) options.ToolChoice = ResponseToolChoice.CreateRequiredChoice(); } } + + private void SetResponseFormat(CreateResponseOptions options, AgentLlmConfig? llmConfig) + { + var format = _state.GetState("response_format").IfNullOrEmptyAs(llmConfig?.ResponseFormat); + var responseFormat = GetResponseTextFormat(format); + options.TextOptions = responseFormat != null ? new ResponseTextOptions + { + TextFormat = responseFormat + } : null; + } #endregion }