diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs index 75e3aa93..7c7c5325 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentLlmConfig.cs @@ -41,4 +41,49 @@ public class AgentLlmConfig [JsonPropertyName("reasoning_effort_level")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ReasoningEffortLevel { get; set; } + + /// + /// Image generation config + /// + [JsonPropertyName("image_generation")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LlmImageGenerationConfig? ImageGeneration { get; set; } + + /// + /// Image edit config + /// + [JsonPropertyName("image_edit")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LlmImageEditConfig? ImageEdit { get; set; } + + /// + /// Audio transcription config + /// + [JsonPropertyName("audio_transcription")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LlmAudioTranscriptionConfig? AudioTranscription { get; set; } + + /// + /// Realtime config + /// + [JsonPropertyName("realtime")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LlmRealtimeConfig? Realtime { get; set; } } + + +public class LlmImageGenerationConfig : LlmProviderModel +{ +} + +public class LlmImageEditConfig : LlmProviderModel +{ +} + +public class LlmRealtimeConfig : LlmProviderModel +{ +} + +public class LlmAudioTranscriptionConfig : LlmProviderModel +{ +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs b/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs index 1d88942c..899f6e7a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Models/LlmConfigBase.cs @@ -1,6 +1,6 @@ namespace BotSharp.Abstraction.Models; -public class LlmConfigBase : LlmBase +public class LlmConfigBase : LlmProviderModel { /// /// Llm maximum output tokens @@ -13,15 +13,13 @@ public class LlmConfigBase : LlmBase public string? ReasoningEffortLevel { get; set; } } -public class LlmBase +public class LlmProviderModel { - /// - /// Llm provider - /// - public string? LlmProvider { get; set; } + [JsonPropertyName("provider")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Provider { get; set; } - /// - /// Llm model - /// - public string? LlmModel { get; set; } + [JsonPropertyName("model")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Model { get; set; } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.SelectFile.cs b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.SelectFile.cs index 50264576..a4cf2d88 100644 --- a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.SelectFile.cs +++ b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.SelectFile.cs @@ -153,8 +153,8 @@ public partial class FileInstructService // Get ai response - var provider = options.LlmProvider ?? "openai"; - var model = options?.LlmModel ?? "gpt-5-mini"; + var provider = options.Provider ?? "openai"; + var model = options?.Model ?? "gpt-5-mini"; var completion = CompletionProvider.GetChatCompletion(_services, provider: provider, model: model); var response = await completion.GetChatCompletions(agent, innerDialogs); diff --git a/src/Plugins/BotSharp.Plugin.AudioHandler/Functions/ReadAudioFn.cs b/src/Plugins/BotSharp.Plugin.AudioHandler/Functions/ReadAudioFn.cs index 7306bb2a..4dd1ada3 100644 --- a/src/Plugins/BotSharp.Plugin.AudioHandler/Functions/ReadAudioFn.cs +++ b/src/Plugins/BotSharp.Plugin.AudioHandler/Functions/ReadAudioFn.cs @@ -34,9 +34,12 @@ public class ReadAudioFn : IFunctionCallback public async Task Execute(RoleDialogModel message) { var args = JsonSerializer.Deserialize(message.FunctionArgs, _options.JsonSerializerOptions); + var agentService = _services.GetRequiredService(); var conv = _services.GetRequiredService(); var routingCtx = _services.GetRequiredService(); + var agent = await agentService.GetAgent(message.CurrentAgentId); + var wholeDialogs = routingCtx.GetDialogs(); if (wholeDialogs.IsNullOrEmpty()) { @@ -44,7 +47,7 @@ public class ReadAudioFn : IFunctionCallback } var dialogs = AssembleFiles(conv.ConversationId, wholeDialogs); - var response = await GetAudioTranscription(dialogs); + var response = await GetAudioTranscription(agent, dialogs); message.Content = response; dialogs.ForEach(x => x.Files = null); return true; @@ -54,7 +57,7 @@ public class ReadAudioFn : IFunctionCallback { if (dialogs.IsNullOrEmpty()) { - return new List(); + return []; } var messageId = dialogs.Select(x => x.MessageId).Distinct().ToList(); @@ -85,13 +88,13 @@ public class ReadAudioFn : IFunctionCallback return dialogs; } - private async Task GetAudioTranscription(List dialogs) + private async Task GetAudioTranscription(Agent agent, List dialogs) { - var audioCompletion = PrepareModel(); + var audioCompletion = PrepareModel(agent); var dialog = dialogs.Where(x => !x.Files.IsNullOrEmpty()).LastOrDefault(); var transcripts = new List(); - if (dialog != null) + if (dialog?.Files != null) { foreach (var file in dialog.Files) { @@ -129,9 +132,9 @@ public class ReadAudioFn : IFunctionCallback return string.Join("\r\n\r\n", transcripts); } - private IAudioTranscription PrepareModel() + private IAudioTranscription PrepareModel(Agent agent) { - var (provider, model) = GetLlmProviderModel(); + var (provider, model) = GetLlmProviderModel(agent); return CompletionProvider.GetAudioTranscriber(_services, provider: provider, model: model); } @@ -142,21 +145,18 @@ public class ReadAudioFn : IFunctionCallback || !string.IsNullOrEmpty(FileUtility.GetFileContentType(fileName)); } - private (string, string) GetLlmProviderModel() + private (string, string) GetLlmProviderModel(Agent agent) { - var state = _services.GetRequiredService(); - var llmProviderService = _services.GetRequiredService(); - - var provider = state.GetState("audio_read_llm_provider"); - var model = state.GetState("audio_read_llm_provider"); + var provider = agent?.LlmConfig?.AudioTranscription?.Provider; + var model = agent?.LlmConfig?.AudioTranscription?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { return (provider, model); } - provider = _settings?.Audio?.Reading?.LlmProvider; - model = _settings?.Audio?.Reading?.LlmModel; + provider = _settings?.Audio?.Reading?.Provider; + model = _settings?.Audio?.Reading?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { diff --git a/src/Plugins/BotSharp.Plugin.AudioHandler/Settings/AudioHandlerSettings.cs b/src/Plugins/BotSharp.Plugin.AudioHandler/Settings/AudioHandlerSettings.cs index b6353b05..8c4c1af0 100644 --- a/src/Plugins/BotSharp.Plugin.AudioHandler/Settings/AudioHandlerSettings.cs +++ b/src/Plugins/BotSharp.Plugin.AudioHandler/Settings/AudioHandlerSettings.cs @@ -13,7 +13,7 @@ public class AudioSettings public AudioReadSettings? Reading { get; set; } } -public class AudioReadSettings : LlmBase +public class AudioReadSettings : LlmProviderModel { } #endregion \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs b/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs index 1cac2c81..187e22ae 100644 --- a/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs +++ b/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs @@ -12,7 +12,6 @@ public class PlotChartFn : IFunctionCallback public string Name => "util-chart-plot_chart"; public string Indication => "Plotting chart"; - public PlotChartFn( IServiceProvider services, ILogger logger, @@ -35,8 +34,8 @@ public class PlotChartFn : IFunctionCallback var inst = GetChartPlotInstruction(message.CurrentAgentId); var innerAgent = new Agent { - Id = agent.Id, - Name = agent.Name, + Id = agent?.Id ?? BuiltInAgentId.AIProgrammer, + Name = agent?.Name ?? "AI Programmer", Instruction = inst, LlmConfig = GetLlmConfig(), TemplateDict = new Dictionary @@ -132,16 +131,16 @@ public class PlotChartFn : IFunctionCallback private (string, string) GetLlmProviderModel() { - var provider = "openai"; - var model = "gpt-5"; + var provider = _settings.ChartPlot?.Provider; + var model = _settings.ChartPlot?.Model; - var state = _services.GetRequiredService(); - provider = state.GetState("chart_plot_llm_provider") - .IfNullOrEmptyAs(_settings.ChartPlot?.LlmProvider) - .IfNullOrEmptyAs(provider); - model = state.GetState("chart_plot_llm_model") - .IfNullOrEmptyAs(_settings.ChartPlot?.LlmModel) - .IfNullOrEmptyAs(model); + if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) + { + return (provider, model); + } + + provider = "openai"; + model = "gpt-5"; return (provider, model); } @@ -151,10 +150,6 @@ public class PlotChartFn : IFunctionCallback var maxOutputTokens = _settings?.ChartPlot?.MaxOutputTokens ?? 8192; var reasoningEffortLevel = _settings?.ChartPlot?.ReasoningEffortLevel ?? "minimal"; - var state = _services.GetRequiredService(); - maxOutputTokens = int.TryParse(state.GetState("chart_plot_max_output_tokens"), out var tokens) ? tokens : maxOutputTokens; - reasoningEffortLevel = state.GetState("chart_plot_reasoning_effort_level").IfNullOrEmptyAs(reasoningEffortLevel); - return new AgentLlmConfig { MaxOutputTokens = maxOutputTokens, diff --git a/src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs b/src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs index 8352a848..e38233c3 100644 --- a/src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs +++ b/src/Plugins/BotSharp.Plugin.EmailHandler/Functions/HandleEmailSenderFn.cs @@ -76,8 +76,8 @@ public class HandleEmailSenderFn : IFunctionCallback IsIncludeBotFiles = true, IsAttachFiles = true, MessageLimit = convSettings?.FileSelect?.MessageLimit, - LlmProvider = convSettings?.FileSelect?.LlmProvider, - LlmModel = convSettings?.FileSelect?.LlmModel, + Provider = convSettings?.FileSelect?.Provider, + Model = convSettings?.FileSelect?.Model, MaxOutputTokens = convSettings?.FileSelect?.MaxOutputTokens, ReasoningEffortLevel = convSettings?.FileSelect?.ReasoningEffortLevel }); diff --git a/src/Plugins/BotSharp.Plugin.FileHandler/Functions/ReadPdfFn.cs b/src/Plugins/BotSharp.Plugin.FileHandler/Functions/ReadPdfFn.cs index a2c2f4e5..c0f9236e 100644 --- a/src/Plugins/BotSharp.Plugin.FileHandler/Functions/ReadPdfFn.cs +++ b/src/Plugins/BotSharp.Plugin.FileHandler/Functions/ReadPdfFn.cs @@ -29,20 +29,15 @@ public class ReadPdfFn : IFunctionCallback public async Task Execute(RoleDialogModel message) { var args = JsonSerializer.Deserialize(message.FunctionArgs); + var agentService = _services.GetRequiredService(); var conv = _services.GetRequiredService(); var routingCtx = _services.GetRequiredService(); - var agentService = _services.GetRequiredService(); - - Agent? fromAgent = null; - if (!string.IsNullOrEmpty(message.CurrentAgentId)) - { - fromAgent = await agentService.GetAgent(message.CurrentAgentId); - } - + + var fromAgent = await agentService.GetAgent(message.CurrentAgentId); var agent = new Agent { - Id = fromAgent?.Id ?? BuiltInAgentId.UtilityAssistant, - Name = fromAgent?.Name ?? "Utility Assistant", + Id = fromAgent?.Id ?? BuiltInAgentId.FileAssistant, + Name = fromAgent?.Name ?? "File Assistant", Instruction = fromAgent?.Instruction ?? args?.UserRequest ?? "Please describe the pdf file(s).", LlmConfig = fromAgent?.LlmConfig ?? new() }; @@ -140,27 +135,16 @@ public class ReadPdfFn : IFunctionCallback private (string, string) GetLlmProviderModel() { - var state = _services.GetRequiredService(); - var llmProviderService = _services.GetRequiredService(); - - var provider = state.GetState("pdf_read_llm_provider"); - var model = state.GetState("pdf_read_llm_model"); + var provider = _settings?.Pdf?.Reading?.Provider; + var model = _settings?.Pdf?.Reading?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { return (provider, model); } - provider = _settings?.Pdf?.Reading?.LlmProvider; - model = _settings?.Pdf?.Reading?.LlmModel; - - if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) - { - return (provider, model); - } - - provider = "openai"; - model = "gpt-5-mini"; + provider = "google-ai"; + model = "gemini-2.0-flash"; return (provider, model); } diff --git a/src/Plugins/BotSharp.Plugin.FileHandler/Settings/FileHandlerSettings.cs b/src/Plugins/BotSharp.Plugin.FileHandler/Settings/FileHandlerSettings.cs index 69889659..efbe8d11 100644 --- a/src/Plugins/BotSharp.Plugin.FileHandler/Settings/FileHandlerSettings.cs +++ b/src/Plugins/BotSharp.Plugin.FileHandler/Settings/FileHandlerSettings.cs @@ -13,7 +13,7 @@ public class PdfSettings public PdfReadSettings? Reading { get; set; } } -public class PdfReadSettings : LlmBase +public class PdfReadSettings : LlmProviderModel { public bool ConvertToImage { get; set; } public string? ImageDetailLevel { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs index d45c7237..31772771 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/EditImageFn.cs @@ -11,7 +11,6 @@ public class EditImageFn : IFunctionCallback private readonly ILogger _logger; private readonly ImageHandlerSettings _settings; - private Agent _agent; private string _conversationId; private string _messageId; @@ -29,11 +28,15 @@ public class EditImageFn : IFunctionCallback { var args = JsonSerializer.Deserialize(message.FunctionArgs); var descrpition = args?.UserRequest ?? string.Empty; + + var agentService = _services.GetRequiredService(); + var agent = await agentService.GetAgent(message.CurrentAgentId); + await Init(message); SetImageOptions(); var image = await SelectImage(descrpition); - var response = await GetImageEditGeneration(message, descrpition, image); + var response = await GetImageEdit(agent, message, descrpition, image); message.Content = response; message.StopCompletion = true; return true; @@ -41,10 +44,8 @@ public class EditImageFn : IFunctionCallback private async Task Init(RoleDialogModel message) { - var agentService = _services.GetRequiredService(); var convService = _services.GetRequiredService(); - _agent = await agentService.GetAgent(message.CurrentAgentId); _conversationId = convService.ConversationId; _messageId = message.MessageId; } @@ -68,15 +69,15 @@ public class EditImageFn : IFunctionCallback IsAttachFiles = true, ContentTypes = [MediaTypeNames.Image.Png, MediaTypeNames.Image.Jpeg], MessageLimit = convSettings?.FileSelect?.MessageLimit, - LlmProvider = convSettings?.FileSelect?.LlmProvider, - LlmModel = convSettings?.FileSelect?.LlmModel, + Provider = convSettings?.FileSelect?.Provider, + Model = convSettings?.FileSelect?.Model, MaxOutputTokens = convSettings?.FileSelect?.MaxOutputTokens, ReasoningEffortLevel = convSettings?.FileSelect?.ReasoningEffortLevel }); return selecteds?.FirstOrDefault(); } - private async Task GetImageEditGeneration(RoleDialogModel message, string description, MessageFileModel? image) + private async Task GetImageEdit(Agent agent, RoleDialogModel message, string description, MessageFileModel? image) { if (image == null) { @@ -85,15 +86,10 @@ public class EditImageFn : IFunctionCallback try { - var (provider, model) = GetLlmProviderModel(); + var (provider, model) = GetLlmProviderModel(agent); var completion = CompletionProvider.GetImageCompletion(_services, provider: provider, model: model); var text = !string.IsNullOrWhiteSpace(description) ? description : message.Content; var dialog = RoleDialogModel.From(message, AgentRole.User, text); - var agent = new Agent - { - Id = _agent?.Id ?? BuiltInAgentId.FileAssistant, - Name = _agent?.Name ?? "File Assistant" - }; var fileStorage = _services.GetRequiredService(); var fileBinary = fileStorage.GetFileBytes(image.FileStorageUrl); @@ -112,7 +108,7 @@ public class EditImageFn : IFunctionCallback return response.Content; } - return await GetImageEditResponse(description, defaultContent: null); + return await GetImageEditResponse(agent, description); } catch (Exception ex) { @@ -122,45 +118,23 @@ public class EditImageFn : IFunctionCallback } } - private async Task GetImageEditResponse(string description, string? defaultContent) + private async Task GetImageEditResponse(Agent agent, string description) { - if (defaultContent != null) - { - return defaultContent; - } - - var llmConfig = _agent.LlmConfig; - var agent = new Agent - { - Id = _agent?.Id ?? BuiltInAgentId.FileAssistant, - Name = _agent?.Name ?? "File Assistant", - LlmConfig = new AgentLlmConfig - { - Provider = llmConfig?.Provider ?? "openai", - Model = llmConfig?.Model ?? "gpt-5-mini", - MaxOutputTokens = llmConfig?.MaxOutputTokens, - ReasoningEffortLevel = llmConfig?.ReasoningEffortLevel - } - }; - return await AiResponseHelper.GetImageGenerationResponse(_services, agent, description); } - private (string, string) GetLlmProviderModel() + private (string, string) GetLlmProviderModel(Agent agent) { - var state = _services.GetRequiredService(); - var llmProviderService = _services.GetRequiredService(); - - var provider = state.GetState("image_edit_llm_provider"); - var model = state.GetState("image_edit_llm_provider"); + var provider = agent?.LlmConfig?.ImageEdit?.Provider; + var model = agent?.LlmConfig?.ImageEdit?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { return (provider, model); } - provider = _settings?.Edit?.LlmProvider; - model = _settings?.Edit?.LlmModel; + provider = _settings?.Edit?.Provider; + model = _settings?.Edit?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs index b73d5869..ccb3e43c 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/GenerateImageFn.cs @@ -9,7 +9,6 @@ public class GenerateImageFn : IFunctionCallback private readonly ILogger _logger; private readonly ImageHandlerSettings _settings; - private Agent _agent; private string _conversationId; private string _messageId; @@ -30,9 +29,9 @@ public class GenerateImageFn : IFunctionCallback SetImageOptions(); var agentService = _services.GetRequiredService(); - _agent = await agentService.GetAgent(message.CurrentAgentId); + var currentAgent = await agentService.GetAgent(message.CurrentAgentId); - var response = await GetImageGeneration(message, args?.ImageDescription); + var response = await GetImageGeneration(currentAgent, message, args?.ImageDescription); message.Content = response; message.StopCompletion = true; return true; @@ -53,18 +52,11 @@ public class GenerateImageFn : IFunctionCallback state.SetState("image_response_format", "bytes"); } - private async Task GetImageGeneration(RoleDialogModel message, string? description) + private async Task GetImageGeneration(Agent agent, RoleDialogModel message, string? description) { try { - var agent = new Agent - { - Id = _agent?.Id ?? BuiltInAgentId.FileAssistant, - Name = _agent?.Name ?? "File Assistant", - Instruction = description - }; - - var (provider, model) = GetLlmProviderModel(); + var (provider, model) = GetLlmProviderModel(agent); var completion = CompletionProvider.GetImageCompletion(_services, provider: provider, model: model); var text = !string.IsNullOrWhiteSpace(description) ? description : message.Content; var dialog = RoleDialogModel.From(message, AgentRole.User, text); @@ -76,7 +68,7 @@ public class GenerateImageFn : IFunctionCallback return result.Content; } - return await GetImageGenerationResponse(description, defaultContent: null); + return await GetImageGenerationResponse(agent, description); } catch (Exception ex) { @@ -86,45 +78,23 @@ public class GenerateImageFn : IFunctionCallback } } - private async Task GetImageGenerationResponse(string description, string? defaultContent) + private async Task GetImageGenerationResponse(Agent agent, string description) { - if (defaultContent != null) - { - return defaultContent; - } - - var llmConfig = _agent.LlmConfig; - var agent = new Agent - { - Id = _agent?.Id ?? BuiltInAgentId.FileAssistant, - Name = _agent?.Name ?? "File Assistant", - LlmConfig = new AgentLlmConfig - { - Provider = llmConfig?.Provider ?? "openai", - Model = llmConfig?.Model ?? "gpt-5-mini", - MaxOutputTokens = llmConfig?.MaxOutputTokens, - ReasoningEffortLevel = llmConfig?.ReasoningEffortLevel - } - }; - return await AiResponseHelper.GetImageGenerationResponse(_services, agent, description); } - private (string, string) GetLlmProviderModel() + private (string, string) GetLlmProviderModel(Agent agent) { - var state = _services.GetRequiredService(); - var llmProviderService = _services.GetRequiredService(); - - var provider = state.GetState("image_generate_llm_provider"); - var model = state.GetState("image_generate_llm_model"); + var provider = agent?.LlmConfig?.ImageGeneration?.Provider; + var model = agent?.LlmConfig?.ImageGeneration?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { return (provider, model); } - provider = _settings?.Generation?.LlmProvider; - model = _settings?.Generation?.LlmModel; + provider = _settings?.Generation?.Provider; + model = _settings?.Generation?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ReadImageFn.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ReadImageFn.cs index 236e9f60..9a42f47d 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ReadImageFn.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Functions/ReadImageFn.cs @@ -30,16 +30,11 @@ public class ReadImageFn : IFunctionCallback public async Task Execute(RoleDialogModel message) { var args = JsonSerializer.Deserialize(message.FunctionArgs); + var agentService = _services.GetRequiredService(); var conv = _services.GetRequiredService(); var routingCtx = _services.GetRequiredService(); - var agentService = _services.GetRequiredService(); - - Agent? fromAgent = null; - if (!string.IsNullOrEmpty(message.CurrentAgentId)) - { - fromAgent = await agentService.GetAgent(message.CurrentAgentId); - } - + + var fromAgent = await agentService.GetAgent(message.CurrentAgentId); var agent = new Agent { Id = fromAgent?.Id ?? BuiltInAgentId.FileAssistant, @@ -133,19 +128,8 @@ public class ReadImageFn : IFunctionCallback private (string, string) GetLlmProviderModel() { - var state = _services.GetRequiredService(); - var llmProviderService = _services.GetRequiredService(); - - var provider = state.GetState("image_read_llm_provider"); - var model = state.GetState("image_read_llm_model"); - - if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) - { - return (provider, model); - } - - provider = _settings?.Reading?.LlmProvider; - model = _settings?.Reading?.LlmModel; + var provider = _settings?.Reading?.Provider; + var model = _settings?.Reading?.Model; if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) { diff --git a/src/Plugins/BotSharp.Plugin.ImageHandler/Settings/ImageHandlerSettings.cs b/src/Plugins/BotSharp.Plugin.ImageHandler/Settings/ImageHandlerSettings.cs index b8f147b9..81a11c8d 100644 --- a/src/Plugins/BotSharp.Plugin.ImageHandler/Settings/ImageHandlerSettings.cs +++ b/src/Plugins/BotSharp.Plugin.ImageHandler/Settings/ImageHandlerSettings.cs @@ -9,17 +9,17 @@ public class ImageHandlerSettings public ImageEditSettings? Edit { get; set; } } -public class ImageReadSettings : LlmBase +public class ImageReadSettings : LlmProviderModel { public string? ImageDetailLevel { get; set; } } -public class ImageGenerationSettings : LlmBase +public class ImageGenerationSettings : LlmProviderModel { } -public class ImageEditSettings : LlmBase +public class ImageEditSettings : LlmProviderModel { public SettingBase? ImageConverter { get; set; } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs index 0a69b7a8..45a1e778 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs @@ -186,16 +186,16 @@ public class PyProgrammerFn : IFunctionCallback private (string, string) GetLlmProviderModel() { - var provider = "openai"; - var model = "gpt-5"; + var provider = _settings.CodeGeneration?.Provider; + var model = _settings.CodeGeneration?.Model; - var state = _services.GetRequiredService(); - provider = state.GetState("py_intepreter_llm_provider") - .IfNullOrEmptyAs(_settings.CodeGeneration?.LlmProvider) - .IfNullOrEmptyAs(provider); - model = state.GetState("py_intepreter_llm_model") - .IfNullOrEmptyAs(_settings.CodeGeneration?.LlmModel) - .IfNullOrEmptyAs(model); + if (!string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(model)) + { + return (provider, model); + } + + provider = "openai"; + model = "gpt-5"; return (provider, model); } @@ -205,10 +205,6 @@ public class PyProgrammerFn : IFunctionCallback var maxOutputTokens = _settings?.CodeGeneration?.MaxOutputTokens ?? 8192; var reasoningEffortLevel = _settings?.CodeGeneration?.ReasoningEffortLevel ?? "minimal"; - var state = _services.GetRequiredService(); - maxOutputTokens = int.TryParse(state.GetState("py_intepreter_max_output_tokens"), out var tokens) ? tokens : maxOutputTokens; - reasoningEffortLevel = state.GetState("py_intepreter_reasoning_effort_level").IfNullOrEmptyAs(reasoningEffortLevel); - return new AgentLlmConfig { MaxOutputTokens = maxOutputTokens, diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index b067b052..276f853e 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -301,8 +301,8 @@ "MinTimeSecondsBetweenMessages": 2 }, "FileSelect": { - "LlmProvider": "openai", - "LlmModel": "gpt-5-mini", + "Provider": "openai", + "Model": "gpt-5-mini", "MaxOutputTokens": 8192, "ReasoningEffortLevel": "low", "MessageLimit": 50 @@ -433,8 +433,8 @@ "FileHandler": { "Pdf": { "Reading": { - "LlmProvider": "google-ai", - "LlmModel": "gemini-2.0-flash", + "Provider": "google-ai", + "Model": "gemini-2.0-flash", "ConvertToImage": false, "ImageDetailLevel": "auto", "ImageConverter": { @@ -446,17 +446,17 @@ "ImageHandler": { "Reading": { - "LlmProvider": "openai", - "LlmModel": "gpt-5-mini", + "Provider": "openai", + "Model": "gpt-5-mini", "ImageDetailLevel": "auto" }, "Generation": { - "LlmProvider": "openai", - "LlmModel": "gpt-image-1" + "Provider": "openai", + "Model": "gpt-image-1" }, "Edit": { - "LlmProvider": "openai", - "LlmModel": "gpt-image-1", + "Provider": "openai", + "Model": "gpt-image-1", "ImageConverter": { "Provider": "image-handler" } @@ -466,8 +466,8 @@ "AudioHandler": { "Audio": { "Reading": { - "LlmProvider": "openai", - "LlmModel": "gpt-4o-mini-transcribe" + "Provider": "openai", + "Model": "gpt-4o-mini-transcribe" } } }, @@ -486,8 +486,8 @@ "ChartHandler": { "ChartPlot": { - "LlmProvider": "openai", - "LlmModel": "gpt-5", + "Provider": "openai", + "Model": "gpt-5", "MaxOutputTokens": 8192, "ReasoningEffortLevel": "minimal", "MessageLimit": 50 @@ -570,8 +570,8 @@ "InstallLocation": "C:/Users/xxx/AppData/Local/Programs/Python/Python313/python313.dll", "PythonVersion": "3.13.3", "CodeGeneration": { - "LlmProvider": "openai", - "LlmModel": "gpt-5", + "Provider": "openai", + "Model": "gpt-5", "MaxOutputTokens": 8192, "ReasoningEffortLevel": "minimal", "MessageLimit": 50