From 1be9ffebaaab54934c8bfd0007991dec847a53f1 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Tue, 30 Sep 2025 15:26:32 -0500 Subject: [PATCH] init agent code --- .../Agents/Models/AgentCodeScript.cs | 22 +++++++ .../CodeInterpreter/ICodeInterpretService.cs | 2 +- .../Instructs/IInstructService.cs | 4 +- .../Instructs/Models/CodeInstructOptions.cs | 2 +- .../Repositories/IBotSharpRepository.cs | 9 ++- .../Services/InstructService.Execute.cs | 31 +++++++--- .../FileRepository.AgentCode.cs | 61 +++++++++++++++++++ .../FileRepository/FileRepository.cs | 1 + .../Controllers/InstructModeController.cs | 1 - .../Services/PyInterpretService.cs | 6 +- 10 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCodeScript.cs create mode 100644 src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.AgentCode.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCodeScript.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCodeScript.cs new file mode 100644 index 00000000..ca328d13 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCodeScript.cs @@ -0,0 +1,22 @@ +namespace BotSharp.Abstraction.Agents.Models; + +public class AgentCodeScript +{ + public string Name { get; set; } + public string Content { get; set; } + + public AgentCodeScript() + { + } + + public AgentCodeScript(string name, string content) + { + Name = name; + Content = content; + } + + public override string ToString() + { + return Name; + } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs index 306ab242..49b6b91d 100644 --- a/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/CodeInterpreter/ICodeInterpretService.cs @@ -6,5 +6,5 @@ public interface ICodeInterpretService { string Provider { get; } - Task RunCode(string code, IEnumerable? arguments = null, CodeInterpretOptions? options = null); + Task RunCode(string codeScript, IEnumerable? arguments = null, CodeInterpretOptions? options = null); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs index 00d7534a..3fe1c03f 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs @@ -10,12 +10,12 @@ public interface IInstructService /// /// /// - /// + /// /// /// /// Task Execute(string agentId, RoleDialogModel message, - string? instruction = null, string? llmTemplateName = null, + string? instruction = null, string? templateName = null, IEnumerable? files = null, CodeInstructOptions? codeOptions = null); /// diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/CodeInstructOptions.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/CodeInstructOptions.cs index 9b9265f4..673e3825 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/CodeInstructOptions.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/CodeInstructOptions.cs @@ -2,6 +2,6 @@ namespace BotSharp.Abstraction.Instructs.Models; public class CodeInstructOptions { - public string? CodeTemplateName { get; set; } + public string? CodeScriptName { get; set; } public string? CodeInterpretProvider { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 8e0e2d55..f13af9a6 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -85,7 +85,6 @@ public interface IBotSharpRepository : IHaveServiceProvider => throw new NotImplementedException(); bool PatchAgentTemplate(string agentId, AgentTemplate template) => throw new NotImplementedException(); - bool UpdateAgentLabels(string agentId, List labels) => throw new NotImplementedException(); bool AppendAgentLabels(string agentId, List labels) @@ -109,6 +108,14 @@ public interface IBotSharpRepository : IHaveServiceProvider => throw new NotImplementedException(); #endregion + #region Agent Code + string? GetAgentCodeScript(string agentId, string scriptName) + => throw new NotImplementedException(); + + bool UpdateAgentCodeScript(string agentId, AgentCodeScript script) + => throw new NotImplementedException(); + #endregion + #region Conversation void CreateNewConversation(Conversation conversation) => throw new NotImplementedException(); diff --git a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs index e09caf01..85960878 100644 --- a/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs +++ b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs @@ -12,7 +12,7 @@ public partial class InstructService string agentId, RoleDialogModel message, string? instruction = null, - string? llmTemplateName = null, + string? templateName = null, IEnumerable? files = null, CodeInstructOptions? codeOptions = null) { @@ -22,7 +22,7 @@ public partial class InstructService var response = new InstructResult { MessageId = message.MessageId, - Template = codeOptions?.CodeTemplateName ?? llmTemplateName + Template = codeOptions?.CodeScriptName ?? templateName }; @@ -40,23 +40,36 @@ public partial class InstructService } // Run code template - if (!string.IsNullOrWhiteSpace(codeOptions?.CodeTemplateName)) + if (!string.IsNullOrWhiteSpace(codeOptions?.CodeScriptName)) { var codeInterpreter = _services.GetServices() .FirstOrDefault(x => x.Provider.IsEqualTo(codeOptions?.CodeInterpretProvider.IfNullOrEmptyAs("python-interpreter"))); if (codeInterpreter == null) { - var error = "No code interpreter found."; + var error = $"No code interpreter found. (Agent: {agentId}, Code interpreter: {codeOptions.CodeInterpretProvider})"; _logger.LogError(error); response.Text = error; } else { + var db = _services.GetRequiredService(); var state = _services.GetRequiredService(); + var arguments = state.GetStates().Select(x => new KeyValue(x.Key, x.Value)); - var result = await codeInterpreter.RunCode("", arguments); - response.Text = result?.Result?.ToString(); + var codeScript = db.GetAgentCodeScript(agentId, codeOptions.CodeScriptName); + + if (string.IsNullOrWhiteSpace(codeScript)) + { + var error = $"Empty code script. (Agent: {agentId}, Code script: {codeOptions.CodeScriptName})"; + _logger.LogError(error); + response.Text = error; + } + else + { + var result = await codeInterpreter.RunCode(codeScript, arguments); + response.Text = result?.Result?.ToString(); + } } return response; } @@ -83,9 +96,9 @@ public partial class InstructService var model = string.Empty; // Render prompt - var prompt = string.IsNullOrEmpty(llmTemplateName) ? + var prompt = string.IsNullOrEmpty(templateName) ? agentService.RenderInstruction(agent) : - agentService.RenderTemplate(agent, llmTemplateName); + agentService.RenderTemplate(agent, templateName); var completer = CompletionProvider.GetCompletion(_services, agentConfig: agent.LlmConfig); @@ -136,7 +149,7 @@ public partial class InstructService AgentId = agentId, Provider = provider, Model = model, - TemplateName = llmTemplateName, + TemplateName = templateName, UserMessage = prompt, SystemInstruction = instruction, CompletionText = response.Text diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.AgentCode.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.AgentCode.cs new file mode 100644 index 00000000..b8c18ddd --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.AgentCode.cs @@ -0,0 +1,61 @@ +using System.IO; + +namespace BotSharp.Core.Repository; + +public partial class FileRepository +{ + #region Code + public string? GetAgentCodeScript(string agentId, string scriptName) + { + if (string.IsNullOrWhiteSpace(agentId) + || string.IsNullOrWhiteSpace(scriptName)) + { + return null; + } + + var dir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId, AGENT_CODE_FOLDER); + if (!Directory.Exists(dir)) + { + return null; + } + + foreach (var file in Directory.GetFiles(dir)) + { + var fileName = Path.GetFileName(file); + if (scriptName.IsEqualTo(fileName)) + { + return File.ReadAllText(file); + } + } + return string.Empty; + } + + public bool UpdateAgentCodeScript(string agentId, AgentCodeScript script) + { + if (string.IsNullOrEmpty(agentId) || script == null) + { + return false; + } + + var dir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId, AGENT_CODE_FOLDER); + if (!Directory.Exists(dir)) + { + return false; + } + + var found = Directory.GetFiles(dir).FirstOrDefault(f => + { + var fileName = Path.GetFileName(f); + return fileName.IsEqualTo(script.Name); + }); + + if (found == null) + { + return false; + } + + File.WriteAllText(found, script.Content); + return true; + } + #endregion +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs index 8e448c25..78ff764c 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs @@ -26,6 +26,7 @@ public partial class FileRepository : IBotSharpRepository private const string AGENT_FUNCTIONS_FOLDER = "functions"; private const string AGENT_TEMPLATES_FOLDER = "templates"; private const string AGENT_RESPONSES_FOLDER = "responses"; + private const string AGENT_CODE_FOLDER = "codes"; private const string AGENT_TASKS_FOLDER = "tasks"; private const string AGENT_TASK_PREFIX = "#metadata"; private const string AGENT_TASK_SUFFIX = "/metadata"; diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs index ad4904c0..cf076259 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs @@ -42,7 +42,6 @@ public class InstructModeController : ControllerBase codeOptions: input.CodeOptions); result.States = state.GetStates(); - return result; } diff --git a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs index a88e3a7c..5f7a8961 100644 --- a/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs +++ b/src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyInterpretService.cs @@ -20,7 +20,7 @@ public class PyInterpretService : ICodeInterpretService public string Provider => "python-interpreter"; - public async Task RunCode(string code, + public async Task RunCode(string codeScript, IEnumerable? arguments = null, CodeInterpretOptions? options = null) { try @@ -38,7 +38,7 @@ public class PyInterpretService : ICodeInterpretService // Set global items using var globals = new PyDict(); - if (code.Contains("__main__") == true) + if (codeScript.Contains("__main__") == true) { globals.SetItem("__name__", new PyString("__main__")); } @@ -61,7 +61,7 @@ public class PyInterpretService : ICodeInterpretService } // Execute Python script - PythonEngine.Exec(code, globals); + PythonEngine.Exec(codeScript, globals); // Get result var result = stringIO.getvalue().ToString();