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.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs
index 23e78a97..0e8953be 100644
--- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/Models/CodeInterpretOptions.cs
@@ -1,6 +1,11 @@
+using System.Threading;
+
namespace BotSharp.Abstraction.CodeInterpreter.Models;
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.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/CodeInterpreter/CodeScriptExecutor.cs b/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs
new file mode 100644
index 00000000..0fea0fa1
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core/CodeInterpreter/CodeScriptExecutor.cs
@@ -0,0 +1,34 @@
+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 default(T);
+ }
+ 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/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/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/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/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 30d30658..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;
@@ -66,30 +66,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 +80,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)
@@ -148,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/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 740499d5..46ed2e47 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,61 @@ 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?.UseMutex == 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;
@@ -45,7 +81,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 ?? "script.py"));
foreach (var arg in options.Arguments)
{
@@ -64,28 +100,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();
+ }
}
}
}
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 96%
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
index e98757cd..82f89b85 100644
--- 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
@@ -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.