From edd2ad6002bbba1b6f3c16f5cf3cdf80730f31c5 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Tue, 7 Oct 2025 21:57:08 -0500 Subject: [PATCH 1/7] refine running py code script --- .../CodeInterpreter/ICodeInterpretService.cs | 1 + .../Models/CodeInterpretOptions.cs | 4 + .../CodeInterpreter/CodeScriptExecutor.cs | 38 ++++++++ .../Conversations/ConversationPlugin.cs | 2 + .../Functions/PyProgrammerFn.cs | 94 ++++++++++++------- .../Services/PyInterpretService.cs | 82 +++++++++++----- 6 files changed, 168 insertions(+), 53 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs index bdc10f5c..58e55438 100644 --- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.CodeInterpreter.Models; +using System.Threading; namespace BotSharp.Abstraction.CodeInterpreter; diff --git a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs index 23e78a97..46f05ebd 100644 --- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs +++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs @@ -1,6 +1,10 @@ +using System.Threading; + namespace BotSharp.Abstraction.CodeInterpreter.Models; public class CodeInterpretOptions { public IEnumerable? Arguments { get; set; } + public bool LockFree { get; set; } + public CancellationToken? CancellationToken { get; set; } } diff --git a/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs b/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs new file mode 100644 index 00000000..5b544f11 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs @@ -0,0 +1,38 @@ +using BotSharp.Abstraction.CodeInterpreter.Models; + +namespace BotSharp.Core.CodeInterpreter; + +public class CodeScriptExecutor +{ + private readonly ILogger _logger; + private readonly SemaphoreSlim _semLock = new(initialCount: 1, maxCount: 1); + + public CodeScriptExecutor( + ILogger logger) + { + _logger = logger; + } + + public async Task Execute(Func> func, CancellationToken cancellationToken = default) + { + await _semLock.WaitAsync(cancellationToken); + + try + { + return await func(); + } + catch (Exception ex) + { + _logger.LogError(ex, $"Error in {nameof(CodeScriptExecutor)}."); + return new CodeInterpretResult + { + Success = false, + ErrorMsg = ex.Message + }; + } + finally + { + _semLock.Release(); + } + } +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs b/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs index 64899ec4..798fe307 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs @@ -8,6 +8,7 @@ using BotSharp.Abstraction.Planning; using BotSharp.Abstraction.Plugins.Models; using BotSharp.Abstraction.Settings; using BotSharp.Abstraction.Templating; +using BotSharp.Core.CodeInterpreter; using BotSharp.Core.Instructs; using BotSharp.Core.MessageHub; using BotSharp.Core.MessageHub.Observers; @@ -70,6 +71,7 @@ public class ConversationPlugin : IBotSharpPlugin services.AddScoped(); services.AddScoped(); + services.AddSingleton(); } public bool AttachMenu(List menu) diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs index 30d30658..fb0b12c0 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.Extensions.Logging; using Python.Runtime; using System.Text.Json; @@ -66,30 +67,10 @@ public class PyProgrammerFn : IFunctionCallback try { - using (Py.GIL()) + var (isSuccess, result) = InnerRunCode(ret.PythonCode); + if (isSuccess) { - // Import necessary Python modules - dynamic sys = Py.Import("sys"); - dynamic io = Py.Import("io"); - - // Redirect standard output/error to capture it - dynamic stringIO = io.StringIO(); - sys.stdout = stringIO; - sys.stderr = stringIO; - - // Set global items - using var globals = new PyDict(); - if (ret.PythonCode?.Contains("__main__") == true) - { - globals.SetItem("__name__", new PyString("__main__")); - } - - // Execute Python script - PythonEngine.Exec(ret.PythonCode, globals); - - // Get result - var result = stringIO.getvalue()?.ToString() as string; - message.Content = result?.TrimEnd('\r', '\n') ?? string.Empty; + message.Content = result; message.RichContent = new RichContent { Recipient = new Recipient { Id = convService.ConversationId }, @@ -100,21 +81,70 @@ public class PyProgrammerFn : IFunctionCallback } }; message.StopCompletion = true; + } + else + { + message.Content = result; + } + } + catch (Exception ex) + { + var errorMsg = $"Error when executing python code. {ex.Message}"; + message.Content = errorMsg; + _logger.LogError(ex, errorMsg); + } - // Restore the original stdout/stderr + return true; + } + + /// + /// Run python code script => (isSuccess, result) + /// + /// + /// + private (bool, string) InnerRunCode(string codeScript) + { + using (Py.GIL()) + { + // Import necessary Python modules + dynamic sys = Py.Import("sys"); + dynamic io = Py.Import("io"); + + try + { + // Redirect standard output/error to capture it + dynamic stringIO = io.StringIO(); + sys.stdout = stringIO; + sys.stderr = stringIO; + + // Set global items + using var globals = new PyDict(); + if (codeScript?.Contains("__main__") == true) + { + globals.SetItem("__name__", new PyString("__main__")); + } + + // Execute Python script + PythonEngine.Exec(codeScript, globals); + + // Get result + var result = stringIO.getvalue()?.ToString() as string; + return (true, result?.TrimEnd('\r', '\n') ?? string.Empty); + } + catch (Exception ex) + { + var errorMsg = $"Error when executing inner python code. {ex.Message}"; + _logger.LogError(ex, errorMsg); + return (false, errorMsg); + } + finally + { + // Restore the original stdout/stderr/argv sys.stdout = sys.__stdout__; sys.stderr = sys.__stderr__; sys.argv = new PyList(); } } - catch (Exception ex) - { - var errorMsg = $"Error when executing python code."; - message.Content = $"{errorMsg} {ex.Message}"; - _logger.LogError(ex, errorMsg); - } - - return true; } private async Task GetChatCompletion(Agent agent, List dialogs) diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs index 740499d5..34a1f03e 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs @@ -1,5 +1,7 @@ +using BotSharp.Core.CodeInterpreter; using Microsoft.Extensions.Logging; using Python.Runtime; +using System.Threading; using System.Threading.Tasks; namespace BotSharp.Plugin.PythonInterpreter.Services; @@ -8,27 +10,63 @@ public class PyInterpretService : ICodeInterpretService { private readonly IServiceProvider _services; private readonly ILogger _logger; + private readonly CodeScriptExecutor _executor; public PyInterpretService( IServiceProvider services, - ILogger logger) + ILogger logger, + CodeScriptExecutor executor) { _services = services; _logger = logger; + _executor = executor; } public string Provider => "botsharp-py-interpreter"; public async Task RunCode(string codeScript, CodeInterpretOptions? options = null) + { + if (options?.LockFree != true) + { + return await _executor.Execute(async () => + { + return InnerRunCode(codeScript, options); + }, cancellationToken: options?.CancellationToken ?? CancellationToken.None); + + } + + return InnerRunCode(codeScript, options); + } + + private CodeInterpretResult InnerRunCode(string codeScript, CodeInterpretOptions? options = null) { try { - using (Py.GIL()) - { - // Import necessary Python modules - dynamic sys = Py.Import("sys"); - dynamic io = Py.Import("io"); + return CoreRun(codeScript, options); + } + catch (Exception ex) + { + var errorMsg = $"Error when executing inner python code in {nameof(PyInterpretService)}: {Provider}."; + _logger.LogError(ex, errorMsg); + return new CodeInterpretResult + { + Success = false, + ErrorMsg = errorMsg + }; + } + } + + private CodeInterpretResult CoreRun(string codeScript, CodeInterpretOptions? options = null) + { + using (Py.GIL()) + { + // Import necessary Python modules + dynamic sys = Py.Import("sys"); + dynamic io = Py.Import("io"); + + try + { // Redirect standard output/error to capture it dynamic stringIO = io.StringIO(); sys.stdout = stringIO; @@ -64,28 +102,30 @@ public class PyInterpretService : ICodeInterpretService // Get result var result = stringIO.getvalue()?.ToString() as string; - // Restore the original stdout/stderr - sys.stdout = sys.__stdout__; - sys.stderr = sys.__stderr__; - sys.argv = new PyList(); - return new CodeInterpretResult { Result = result?.TrimEnd('\r', '\n'), Success = true }; } - } - catch (Exception ex) - { - var errorMsg = $"Error when executing python code in {nameof(PyInterpretService)}: {Provider}. {ex.Message}"; - _logger.LogError(ex, errorMsg); - - return new CodeInterpretResult + catch (Exception ex) { - Success = false, - ErrorMsg = errorMsg - }; + var errorMsg = $"Error when executing core python code in {nameof(PyInterpretService)}: {Provider}. {ex.Message}"; + _logger.LogError(ex, errorMsg); + + return new CodeInterpretResult + { + Success = false, + ErrorMsg = errorMsg + }; + } + finally + { + // Restore the original stdout/stderr/argv + sys.stdout = sys.__stdout__; + sys.stderr = sys.__stderr__; + sys.argv = new PyList(); + } } } } From 4e0801780b41bb18fec9e37afcad25b40ef19103 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Tue, 7 Oct 2025 21:58:54 -0500 Subject: [PATCH 2/7] clean code --- .../CodeInterpreter/ICodeInterpretService.cs | 1 - .../Functions/PyProgrammerFn.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs index 58e55438..bdc10f5c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.CodeInterpreter.Models; -using System.Threading; namespace BotSharp.Abstraction.CodeInterpreter; diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs index fb0b12c0..1cf14ed8 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs @@ -1,4 +1,3 @@ -using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.Extensions.Logging; using Python.Runtime; using System.Text.Json; From 605109bcca08a961100b9abd4ddf4b3294b83b9b Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Tue, 7 Oct 2025 22:38:09 -0500 Subject: [PATCH 3/7] add ai programmer and file assistant --- .../Agents/Enums/BuiltInAgentId.cs | 10 ++++++++ .../BotSharp.Core.Crontab.csproj | 1 + .../BotSharp.Core/BotSharp.Core.csproj | 25 +++++++++++++++---- .../FileInstructService.SelectFile.cs | 4 +-- .../agent.json | 18 +++++++++++++ .../instructions/instruction.liquid | 1 + .../agent.json | 18 +++++++++++++ .../instructions/instruction.liquid | 1 + .../BotSharp.Plugin.ChartHandler.csproj | 4 +-- .../Functions/PlotChartFn.cs | 4 +-- .../chart-js-generate_instruction.liquid} | 0 .../BotSharp.Plugin.FileHandler.csproj | 4 +++ .../select-chat-file_instruction.liquid} | 0 .../BotSharp.Plugin.PythonInterpreter.csproj | 6 +++-- .../Functions/PyProgrammerFn.cs | 4 +-- .../py-code_generate_instruction.liquid} | 0 16 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/agent.json create mode 100644 src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/instructions/instruction.liquid create mode 100644 src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/agent.json create mode 100644 src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/instructions/instruction.liquid rename src/Plugins/BotSharp.Plugin.ChartHandler/data/agents/{6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-chart-plot_instruction.liquid => c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/chart-js-generate_instruction.liquid} (100%) rename src/{Infrastructure/BotSharp.Core/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-file-select_file_instruction.liquid => Plugins/BotSharp.Plugin.FileHandler/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/templates/select-chat-file_instruction.liquid} (100%) rename src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/{6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-code-python_generate_instruction.liquid => c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid} (100%) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs index 82b0efab..367fd08b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/BuiltInAgentId.cs @@ -51,4 +51,14 @@ public static class BuiltInAgentId /// Translates user-defined natural language rules into programmatic code /// public const string RulesInterpreter = "201e49a2-40b3-4ccd-b8cc-2476565a1b40"; + + /// + /// Generate code script + /// + public const string AIProgrammer = "c2a2faf6-b8b5-47fe-807b-f4714cf25dd4"; + + /// + /// Handle files + /// + public const string FileAssistant = "f1e09a73-9efe-46ce-ba02-b3aaf96d97e0"; } diff --git a/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj b/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj index 7e92ca1f..1c9d96e5 100644 --- a/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj +++ b/src/Infrastructure/BotSharp.Core.Crontab/BotSharp.Core.Crontab.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index d960ca18..d8afd37b 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -96,13 +96,16 @@ - - + + + + + @@ -172,6 +175,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -193,9 +199,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -208,6 +211,18 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest 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 d2af898b..3b0b724a 100644 --- a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.SelectFile.cs +++ b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.SelectFile.cs @@ -114,8 +114,8 @@ public partial class FileInstructService return new NameDesc(text, desc); }).ToList(); - var agentId = !string.IsNullOrWhiteSpace(options.AgentId) ? options.AgentId : BuiltInAgentId.UtilityAssistant; - var template = !string.IsNullOrWhiteSpace(options.Template) ? options.Template : "util-file-select_file_instruction"; + var agentId = !string.IsNullOrWhiteSpace(options.AgentId) ? options.AgentId : BuiltInAgentId.FileAssistant; + var template = !string.IsNullOrWhiteSpace(options.Template) ? options.Template : "select_chat_file_instruction"; var prompt = db.GetAgentTemplate(agentId, template); var data = new Dictionary diff --git a/src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/agent.json b/src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/agent.json new file mode 100644 index 00000000..31c38e57 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/agent.json @@ -0,0 +1,18 @@ +{ + "id": "c2a2faf6-b8b5-47fe-807b-f4714cf25dd4", + "name": "AI programmer", + "description": "AI programmer is designed to generate code scripts.", + "type": "task", + "createdDateTime": "2025-10-07T10:39:32Z", + "updatedDateTime": "2025-10-07T14:39:32Z", + "iconUrl": "/images/logo.png", + "disabled": false, + "isPublic": true, + "llmConfig": { + "is_inherit": false, + "provider": "openai", + "model": "gpt-5", + "max_recursion_depth": 3, + "reasoning_effort_level": "minimal" + } +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/instructions/instruction.liquid b/src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/instructions/instruction.liquid new file mode 100644 index 00000000..3da026ef --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/instructions/instruction.liquid @@ -0,0 +1 @@ +You are a AI programmer to help coding. \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/agent.json b/src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/agent.json new file mode 100644 index 00000000..8da69b84 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/agent.json @@ -0,0 +1,18 @@ +{ + "id": "f1e09a73-9efe-46ce-ba02-b3aaf96d97e0", + "name": "File Assistant", + "description": "File Assistant is designed to handle files.", + "type": "task", + "createdDateTime": "2025-10-07T10:39:32Z", + "updatedDateTime": "2025-10-07T14:39:32Z", + "iconUrl": "/images/logo.png", + "disabled": false, + "isPublic": true, + "llmConfig": { + "is_inherit": false, + "provider": "openai", + "model": "gpt-5-mini", + "max_recursion_depth": 3, + "reasoning_effort_level": "minimal" + } +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/instructions/instruction.liquid b/src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/instructions/instruction.liquid new file mode 100644 index 00000000..cfc58109 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/instructions/instruction.liquid @@ -0,0 +1 @@ +You are a File Assistant to help handle files. \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.ChartHandler/BotSharp.Plugin.ChartHandler.csproj b/src/Plugins/BotSharp.Plugin.ChartHandler/BotSharp.Plugin.ChartHandler.csproj index 784b2405..1c91204d 100644 --- a/src/Plugins/BotSharp.Plugin.ChartHandler/BotSharp.Plugin.ChartHandler.csproj +++ b/src/Plugins/BotSharp.Plugin.ChartHandler/BotSharp.Plugin.ChartHandler.csproj @@ -13,7 +13,7 @@ - + @@ -23,7 +23,7 @@ PreserveNewest - + PreserveNewest diff --git a/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs b/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs index 1c89478c..1cac2c81 100644 --- a/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs +++ b/src/Plugins/BotSharp.Plugin.ChartHandler/Functions/PlotChartFn.cs @@ -123,8 +123,8 @@ public class PlotChartFn : IFunctionCallback } else { - templateName = "util-chart-plot_instruction"; - templateContent = db.GetAgentTemplate(BuiltInAgentId.UtilityAssistant, templateName); + templateName = "chart-js-generate_instruction"; + templateContent = db.GetAgentTemplate(BuiltInAgentId.AIProgrammer, templateName); } return templateContent; diff --git a/src/Plugins/BotSharp.Plugin.ChartHandler/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-chart-plot_instruction.liquid b/src/Plugins/BotSharp.Plugin.ChartHandler/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/chart-js-generate_instruction.liquid similarity index 100% rename from src/Plugins/BotSharp.Plugin.ChartHandler/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-chart-plot_instruction.liquid rename to src/Plugins/BotSharp.Plugin.ChartHandler/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/chart-js-generate_instruction.liquid diff --git a/src/Plugins/BotSharp.Plugin.FileHandler/BotSharp.Plugin.FileHandler.csproj b/src/Plugins/BotSharp.Plugin.FileHandler/BotSharp.Plugin.FileHandler.csproj index fe05a7e4..4eb83e01 100644 --- a/src/Plugins/BotSharp.Plugin.FileHandler/BotSharp.Plugin.FileHandler.csproj +++ b/src/Plugins/BotSharp.Plugin.FileHandler/BotSharp.Plugin.FileHandler.csproj @@ -19,6 +19,7 @@ + @@ -46,6 +47,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/Infrastructure/BotSharp.Core/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-file-select_file_instruction.liquid b/src/Plugins/BotSharp.Plugin.FileHandler/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/templates/select-chat-file_instruction.liquid similarity index 100% rename from src/Infrastructure/BotSharp.Core/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-file-select_file_instruction.liquid rename to src/Plugins/BotSharp.Plugin.FileHandler/data/agents/f1e09a73-9efe-46ce-ba02-b3aaf96d97e0/templates/select-chat-file_instruction.liquid diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/BotSharp.Plugin.PythonInterpreter.csproj b/src/Plugins/BotSharp.Plugin.PythonInterpreter/BotSharp.Plugin.PythonInterpreter.csproj index 8b0775e8..54ed1270 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/BotSharp.Plugin.PythonInterpreter.csproj +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/BotSharp.Plugin.PythonInterpreter.csproj @@ -11,7 +11,9 @@ - + + + @@ -21,7 +23,7 @@ PreserveNewest - + PreserveNewest diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs index 1cf14ed8..7be90493 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs @@ -177,8 +177,8 @@ public class PyProgrammerFn : IFunctionCallback } else { - templateName = "util-code-python_generate_instruction"; - templateContent = db.GetAgentTemplate(BuiltInAgentId.UtilityAssistant, templateName); + templateName = "py-code_generate_instruction"; + templateContent = db.GetAgentTemplate(BuiltInAgentId.AIProgrammer, templateName); } return templateContent; diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-code-python_generate_instruction.liquid b/src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid similarity index 100% rename from src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-code-python_generate_instruction.liquid rename to src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid From c30787a8ea69a82c66fecc5ebdaa339ee4caf361 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Tue, 7 Oct 2025 22:42:53 -0500 Subject: [PATCH 4/7] change text --- .../Functions/PyProgrammerFn.cs | 2 +- .../templates/py-code_generate_instruction.liquid | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs index 7be90493..0a69b7a8 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Functions/PyProgrammerFn.cs @@ -8,7 +8,7 @@ namespace BotSharp.Plugin.PythonInterpreter.Functions; public class PyProgrammerFn : IFunctionCallback { public string Name => "util-code-python_programmer"; - public string Indication => "Programming and executing code"; + public string Indication => "Coding"; private readonly IServiceProvider _services; private readonly ILogger _logger; diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid b/src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid index e98757cd..82f89b85 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/data/agents/c2a2faf6-b8b5-47fe-807b-f4714cf25dd4/templates/py-code_generate_instruction.liquid @@ -1,4 +1,4 @@ -You are a Python code generator that can produce python code to fulfill user's requirement. +You are a Python Coding Assistant that can produce python code to fulfill user's requirement. Please read {% if user_requirement != empty %}"User Requirement" and{% endif %} the chat context, and then generate valid python code that can fulfill user's requirement. You must strictly follow the "Hard Requirements", "Code Requirements", and "Response Format" below. From 2079ba3760025c2a9b96b6bb2ca84f3e59e16195 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 8 Oct 2025 15:12:00 -0500 Subject: [PATCH 5/7] remove allow thread --- .../CodeInterpreter/Models/CodeInterpretOptions.cs | 2 +- .../CodeInterpreter/CodeScriptExecutor.cs | 8 ++------ .../Instructs/Services/InstructService.Execute.cs | 3 ++- .../PythonInterpreterPlugin.cs | 14 +++++++++++--- .../Services/PyInterpretService.cs | 12 +----------- 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs index 46f05ebd..2c4e0fc9 100644 --- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs +++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs @@ -4,7 +4,7 @@ namespace BotSharp.Abstraction.CodeInterpreter.Models; public class CodeInterpretOptions { + public string? ScriptName { get; set; } public IEnumerable? Arguments { get; set; } - public bool LockFree { get; set; } public CancellationToken? CancellationToken { get; set; } } diff --git a/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs b/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs index 5b544f11..0fea0fa1 100644 --- a/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs +++ b/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs @@ -13,7 +13,7 @@ public class CodeScriptExecutor _logger = logger; } - public async Task Execute(Func> func, CancellationToken cancellationToken = default) + public async Task Execute(Func> func, CancellationToken cancellationToken = default) { await _semLock.WaitAsync(cancellationToken); @@ -24,11 +24,7 @@ public class CodeScriptExecutor catch (Exception ex) { _logger.LogError(ex, $"Error in {nameof(CodeScriptExecutor)}."); - return new CodeInterpretResult - { - Success = false, - ErrorMsg = ex.Message - }; + return default(T); } finally { diff --git a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs index 11ff7518..daa55803 100644 --- a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs +++ b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs @@ -155,7 +155,7 @@ public partial class InstructService var db = _services.GetRequiredService(); var hooks = _services.GetHooks(agent.Id); - var codeProvider = codeOptions?.CodeInterpretProvider.IfNullOrEmptyAs("botsharp-py-interpreter"); + var codeProvider = codeOptions?.CodeInterpretProvider ?? "botsharp-py-interpreter"; var codeInterpreter = _services.GetServices() .FirstOrDefault(x => x.Provider.IsEqualTo(codeProvider)); @@ -228,6 +228,7 @@ public partial class InstructService // Run code script var result = await codeInterpreter.RunCode(context.CodeScript, options: new() { + ScriptName = scriptName, Arguments = context.Arguments }); diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/PythonInterpreterPlugin.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/PythonInterpreterPlugin.cs index 168d83f8..303ae41a 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/PythonInterpreterPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/PythonInterpreterPlugin.cs @@ -29,6 +29,7 @@ public class PythonInterpreterPlugin : IBotSharpAppPlugin { var sp = app.ApplicationServices; var settings = sp.GetRequiredService(); + var lifetime = app.ApplicationServices.GetRequiredService(); var logger = sp.GetRequiredService>(); var pyLoc = settings.InstallLocation; @@ -38,12 +39,19 @@ public class PythonInterpreterPlugin : IBotSharpAppPlugin { Runtime.PythonDLL = pyLoc; PythonEngine.Initialize(); +#if DEBUG _pyState = PythonEngine.BeginAllowThreads(); +#endif - var lifetime = app.ApplicationServices.GetRequiredService(); lifetime.ApplicationStopping.Register(() => { - PythonEngine.EndAllowThreads(_pyState); - PythonEngine.Shutdown(); + try + { +#if DEBUG + PythonEngine.EndAllowThreads(_pyState); +#endif + PythonEngine.Shutdown(); + } + catch { } }); } else diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs index 34a1f03e..f5688027 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs @@ -1,7 +1,6 @@ using BotSharp.Core.CodeInterpreter; using Microsoft.Extensions.Logging; using Python.Runtime; -using System.Threading; using System.Threading.Tasks; namespace BotSharp.Plugin.PythonInterpreter.Services; @@ -26,15 +25,6 @@ public class PyInterpretService : ICodeInterpretService public async Task RunCode(string codeScript, CodeInterpretOptions? options = null) { - if (options?.LockFree != true) - { - return await _executor.Execute(async () => - { - return InnerRunCode(codeScript, options); - }, cancellationToken: options?.CancellationToken ?? CancellationToken.None); - - } - return InnerRunCode(codeScript, options); } @@ -83,7 +73,7 @@ public class PyInterpretService : ICodeInterpretService var list = new PyList(); if (options?.Arguments?.Any() == true) { - list.Append(new PyString("code.py")); + list.Append(new PyString(options?.ScriptName.IfNullOrEmptyAs("script.py"))); foreach (var arg in options.Arguments) { From 333807ceb7396f8c8dcc093fca1a72cb2baa4883 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 8 Oct 2025 15:25:53 -0500 Subject: [PATCH 6/7] revert --- .../CodeInterpreter/Models/CodeInterpretOptions.cs | 1 + .../codes/src/demo.py | 9 +++++++-- .../Services/PyInterpretService.cs | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs index 2c4e0fc9..0e8953be 100644 --- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs +++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs @@ -6,5 +6,6 @@ public class CodeInterpretOptions { public string? ScriptName { get; set; } public IEnumerable? Arguments { get; set; } + public bool UseMutex { get; set; } public CancellationToken? CancellationToken { get; set; } } diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01e2fc5c-2c89-4ec7-8470-7688608b496c/codes/src/demo.py b/src/Infrastructure/BotSharp.Core/data/agents/01e2fc5c-2c89-4ec7-8470-7688608b496c/codes/src/demo.py index 438a6a87..5b29f4b2 100644 --- a/src/Infrastructure/BotSharp.Core/data/agents/01e2fc5c-2c89-4ec7-8470-7688608b496c/codes/src/demo.py +++ b/src/Infrastructure/BotSharp.Core/data/agents/01e2fc5c-2c89-4ec7-8470-7688608b496c/codes/src/demo.py @@ -1,12 +1,17 @@ import argparse +import json def main(): parser = argparse.ArgumentParser(description="Receive named arguments") parser.add_argument("--first_name", required=True, help="The first name") parser.add_argument("--last_name", required=True, help="The last name") - args = parser.parse_args() - print(f"Hello, {args.first_name} {args.last_name}!") + args, _ = parser.parse_known_args() + obj = { + "first_name": args.first_name, + "last_name":args.last_name + } + print(f"{json.dumps(obj)}") if __name__ == "__main__": main() \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs index f5688027..9041126b 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs @@ -1,6 +1,7 @@ using BotSharp.Core.CodeInterpreter; using Microsoft.Extensions.Logging; using Python.Runtime; +using System.Threading; using System.Threading.Tasks; namespace BotSharp.Plugin.PythonInterpreter.Services; @@ -25,6 +26,13 @@ public class PyInterpretService : ICodeInterpretService public async Task RunCode(string codeScript, CodeInterpretOptions? options = null) { + if (options?.UseMutex == true) + { + return await _executor.Execute(async () => + { + return InnerRunCode(codeScript, options); + }, cancellationToken: options?.CancellationToken ?? CancellationToken.None); + } return InnerRunCode(codeScript, options); } From c20ab2e2e7df0b5c5f0c7f454e6dbfd4a8879fc7 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Wed, 8 Oct 2025 15:28:54 -0500 Subject: [PATCH 7/7] minor change --- .../Services/PyInterpretService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs index 9041126b..46ed2e47 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs @@ -81,7 +81,7 @@ public class PyInterpretService : ICodeInterpretService var list = new PyList(); if (options?.Arguments?.Any() == true) { - list.Append(new PyString(options?.ScriptName.IfNullOrEmptyAs("script.py"))); + list.Append(new PyString(options?.ScriptName ?? "script.py")); foreach (var arg in options.Arguments) {