From 9b662168ff3b09daa7882dbf8b73956d56281c63 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Sun, 23 Feb 2025 22:55:35 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=EF=BC=9A=20Agent=20add=20mcp=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BotSharp.sln | 14 ---- .../Agents/AgentHookBase.cs | 6 ++ .../Agents/Enums/AgentField.cs | 1 + .../BotSharp.Abstraction/Agents/IAgentHook.cs | 2 + .../Agents/Models/Agent.cs | 15 +++- .../Agents/Models/AgentMCP.cs | 65 +++++++++++++++++ .../Agents/Hooks/BasicAgentHook.cs | 58 +++++++++++++++ .../Agents/Services/AgentService.LoadAgent.cs | 5 ++ .../Services/AgentService.UpdateAgent.cs | 2 + .../BotSharp.Core/BotSharp.Core.csproj | 1 + .../BotSharp.Core/MCP/AIFunctionUtilities.cs | 36 +++++++++ .../MCP}/Functions/McpAIFunction.cs | 8 +- .../BotSharp.Core/MCP}/MCPClientManager.cs | 6 +- .../BotSharp.Core/MCP}/McpPlugin.cs | 9 +-- .../MCP}/Settings/MCPSettings.cs | 3 +- .../FileRepository/FileRepository.Agent.cs | 18 +++++ .../ViewModels/Agents/AgentCreationModel.cs | 2 + .../ViewModels/Agents/AgentUpdateModel.cs | 6 ++ .../ViewModels/Agents/AgentViewModel.cs | 2 + .../BotSharp.Plugin.Mcp.csproj | 22 ------ .../Collections/AgentDocument.cs | 1 + .../Models/AgentMcpMongoElement.cs | 73 +++++++++++++++++++ .../Repository/MongoRepository.Agent.cs | 19 +++++ 23 files changed, 317 insertions(+), 57 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs create mode 100644 src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs rename src/{Plugins/BotSharp.Plugin.Mcp => Infrastructure/BotSharp.Core/MCP}/Functions/McpAIFunction.cs (94%) rename src/{Plugins/BotSharp.Plugin.Mcp => Infrastructure/BotSharp.Core/MCP}/MCPClientManager.cs (85%) rename src/{Plugins/BotSharp.Plugin.Mcp => Infrastructure/BotSharp.Core/MCP}/McpPlugin.cs (85%) rename src/{Plugins/BotSharp.Plugin.Mcp => Infrastructure/BotSharp.Core/MCP}/Settings/MCPSettings.cs (74%) delete mode 100644 src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj create mode 100644 src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMcpMongoElement.cs diff --git a/BotSharp.sln b/BotSharp.sln index d8796f8a..d4890be1 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -127,10 +127,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.Rules", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.DeepSeekAI", "src\Plugins\BotSharp.Plugin.DeepSeekAI\BotSharp.Plugin.DeepSeekAI.csproj", "{AF329442-B48E-4B48-A18A-1C869D1BA6F5}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MCP", "MCP", "{B38A04AB-F4BD-4F10-9662-EC110881533B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.Mcp", "src\Plugins\BotSharp.Plugin.Mcp\BotSharp.Plugin.Mcp.csproj", "{9475E249-6964-457C-96C2-3F917111123F}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -523,14 +519,6 @@ Global {AF329442-B48E-4B48-A18A-1C869D1BA6F5}.Release|Any CPU.Build.0 = Release|Any CPU {AF329442-B48E-4B48-A18A-1C869D1BA6F5}.Release|x64.ActiveCfg = Release|Any CPU {AF329442-B48E-4B48-A18A-1C869D1BA6F5}.Release|x64.Build.0 = Release|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Debug|x64.ActiveCfg = Debug|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Debug|x64.Build.0 = Debug|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Release|Any CPU.Build.0 = Release|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Release|x64.ActiveCfg = Release|Any CPU - {9475E249-6964-457C-96C2-3F917111123F}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -592,8 +580,6 @@ Global {F812BAAE-5A7D-4DF7-8E71-70696B51C61F} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749} {AFD64412-4D6A-452E-82A2-79E5D8842E29} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749} {AF329442-B48E-4B48-A18A-1C869D1BA6F5} = {D5293208-2BEF-42FC-A64C-5954F61720BA} - {B38A04AB-F4BD-4F10-9662-EC110881533B} = {2635EC9B-2E5F-4313-AC21-0B847F31F36C} - {9475E249-6964-457C-96C2-3F917111123F} = {B38A04AB-F4BD-4F10-9662-EC110881533B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs index bec14b85..ff52bb46 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs @@ -57,5 +57,11 @@ public abstract class AgentHookBase : IAgentHook public virtual void OnAgentUtilityLoaded(Agent agent) { + + } + + public virtual void OnAgentMCPLoaded(Agent agent) + { + } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs index 0c39a960..e02d02d7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs @@ -19,6 +19,7 @@ public enum AgentField Sample, LlmConfig, Utility, + Mcp, KnowledgeBase, Rule, MaxMessageCount diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs index a3f53fb6..21bf8b5b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs @@ -27,6 +27,8 @@ public interface IAgentHook void OnAgentUtilityLoaded(Agent agent); + void OnAgentMCPLoaded(Agent agent); + /// /// Triggered when agent is loaded completely. /// diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 085b0f9d..bed77d43 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -95,14 +95,18 @@ public class Agent public List Labels { get; set; } = new(); /// - /// Merge utilities from entry agent + /// Merge mcps from entry agent /// public bool MergeUtility { get; set; } /// - /// Agent utilities + /// Agent mcps /// public List Utilities { get; set; } = new(); + /// + /// Agent MCP + /// + public List Mcps { get; set; } = new(); /// /// Agent rules @@ -157,6 +161,7 @@ public class Agent Responses = agent.Responses, Samples = agent.Samples, Utilities = agent.Utilities, + Mcps = agent.Mcps, Knowledges = agent.Knowledges, IsPublic = agent.IsPublic, Disabled = agent.Disabled, @@ -298,4 +303,10 @@ public class Agent LlmConfig = llmConfig; return this; } + + public Agent SetMcps(List mcps) + { + Mcps = mcps ?? []; + return this; + } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs new file mode 100644 index 00000000..98a186dc --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs @@ -0,0 +1,65 @@ +namespace BotSharp.Abstraction.Agents.Models; + +public class AgentMCP +{ + public string Name { get; set; } + + public string ServerId { get; set; } + + public bool Disabled { get; set; } + + public IEnumerable Functions { get; set; } = []; + public IEnumerable Templates { get; set; } = []; + + public AgentMCP() + { + + } + + public AgentMCP( + string name, + IEnumerable? functions = null, + IEnumerable? templates = null) + { + Name = name; + Functions = functions ?? []; + Templates = templates ?? []; + } + + public override string ToString() + { + return Name; + } +} + + +public class MCPFunction : MCPBase +{ + public MCPFunction() + { + + } + + public MCPFunction(string name) + { + Name = name; + } +} + +public class MCPTemplate : MCPBase +{ + public MCPTemplate() + { + + } + + public MCPTemplate(string name) + { + Name = name; + } +} + +public class MCPBase +{ + public string Name { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs index 1101f160..b3bf3868 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs @@ -1,3 +1,6 @@ +using BotSharp.Core.Mcp; +using BotSharp.Core.MCP; + namespace BotSharp.Core.Agents.Hooks; public class BasicAgentHook : AgentHookBase @@ -39,6 +42,36 @@ public class BasicAgentHook : AgentHookBase } } + public override void OnAgentMCPLoaded(Agent agent) + { + if (agent.Type == AgentType.Routing) + return; + + var conv = _services.GetRequiredService(); + var isConvMode = conv.IsConversationMode(); + if (!isConvMode) return; + + agent.SecondaryFunctions ??= []; + agent.SecondaryInstructions ??= []; + agent.Mcps ??= []; + + var (functions, templates) = GetMCPContent(agent); + + foreach (var fn in functions) + { + if (!agent.SecondaryFunctions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase))) + { + agent.SecondaryFunctions.Add(fn); + } + } + + foreach (var prompt in templates) + { + agent.SecondaryInstructions.Add(prompt); + } + } + + private (IEnumerable, IEnumerable) GetUtilityContent(Agent agent) { var db = _services.GetRequiredService(); @@ -82,4 +115,29 @@ public class BasicAgentHook : AgentHookBase return (functionNames, templateNames); } + + private (IEnumerable, IEnumerable) GetMCPContent(Agent agent) + { + List functionDefs = new List(); + IEnumerable templates = new List(); + var mcpClientManager = _services.GetRequiredService(); + var mcps = agent.Mcps; + foreach (var item in mcps) + { + var ua = mcpClientManager.Factory.GetClientAsync(item.ServerId).Result; + if (ua != null) + { + var tools = ua.ListToolsAsync().Result; + var funcnames = item.Functions.Select(x => x.Name).ToList(); + foreach (var tool in tools.Tools.Where(x=> funcnames.Contains(x.Name,StringComparer.OrdinalIgnoreCase))) + { + var funDef = AIFunctionUtilities.MapToFunctionDef(tool); + functionDefs.Add(funDef); + } + } + } + + return (functionDefs, templates); + } + } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs index 15ba26a1..411c2e89 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs @@ -71,6 +71,11 @@ public partial class AgentService { hook.OnAgentUtilityLoaded(agent); } + + if(agent.Mcps != null) + { + hook.OnAgentMCPLoaded(agent); + } hook.OnAgentLoaded(agent); } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index a9cc58d9..8fdb2c9b 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -40,6 +40,7 @@ public partial class AgentService record.Responses = agent.Responses ?? []; record.Samples = agent.Samples ?? []; record.Utilities = agent.Utilities ?? []; + record.Mcps = agent.Mcps ?? []; record.KnowledgeBases = agent.KnowledgeBases ?? []; record.Rules = agent.Rules ?? []; if (agent.LlmConfig != null && !agent.LlmConfig.IsInherit) @@ -106,6 +107,7 @@ public partial class AgentService .SetResponses(foundAgent.Responses) .SetSamples(foundAgent.Samples) .SetUtilities(foundAgent.Utilities) + .SetMcps(foundAgent.Mcps) .SetKnowledgeBases(foundAgent.KnowledgeBases) .SetRules(foundAgent.Rules) .SetLlmConfig(foundAgent.LlmConfig); diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index 37eee3ac..0d684675 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -195,6 +195,7 @@ + diff --git a/src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs b/src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs new file mode 100644 index 00000000..9c40eaa1 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs @@ -0,0 +1,36 @@ +using McpDotNet.Protocol.Types; +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace BotSharp.Core.MCP; + +internal static class AIFunctionUtilities +{ + public static FunctionDef MapToFunctionDef(Tool tool) + { + if (tool == null) + { + throw new ArgumentNullException(nameof(tool)); + } + + var properties = tool.InputSchema?.Properties; + var required = tool.InputSchema?.Required ?? new List(); + + FunctionDef funDef = new FunctionDef + { + Name = tool.Name, + Description = tool.Description?? string.Empty, + Type = "function", + Parameters = new FunctionParametersDef + { + Type = "object", + Properties = properties != null ? JsonSerializer.SerializeToDocument(properties) : JsonDocument.Parse("{}"), + Required = required + } + }; + + return funDef; + } +} diff --git a/src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs b/src/Infrastructure/BotSharp.Core/MCP/Functions/McpAIFunction.cs similarity index 94% rename from src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs rename to src/Infrastructure/BotSharp.Core/MCP/Functions/McpAIFunction.cs index d19ca1e9..b7d36b2f 100644 --- a/src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs +++ b/src/Infrastructure/BotSharp.Core/MCP/Functions/McpAIFunction.cs @@ -1,14 +1,8 @@ -using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions; using McpDotNet.Client; using McpDotNet.Protocol.Types; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; -using System.Threading.Tasks; -namespace BotSharp.Plugin.Mcp.Functions; +namespace BotSharp.Core.Mcp.Functions; public class McpAIFunction : IFunctionCallback { diff --git a/src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs b/src/Infrastructure/BotSharp.Core/MCP/MCPClientManager.cs similarity index 85% rename from src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs rename to src/Infrastructure/BotSharp.Core/MCP/MCPClientManager.cs index e1f01f14..bd115942 100644 --- a/src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs +++ b/src/Infrastructure/BotSharp.Core/MCP/MCPClientManager.cs @@ -1,9 +1,7 @@ -using BotSharp.Plugin.Mcp.Settings; +using BotSharp.Core.Mcp.Settings; using McpDotNet.Client; -using Microsoft.Extensions.Logging; -using System; -namespace BotSharp.Plugin.Mcp; +namespace BotSharp.Core.Mcp; public class MCPClientManager : IDisposable { diff --git a/src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs b/src/Infrastructure/BotSharp.Core/MCP/McpPlugin.cs similarity index 85% rename from src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs rename to src/Infrastructure/BotSharp.Core/MCP/McpPlugin.cs index 2bfda270..7ab8d249 100644 --- a/src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs +++ b/src/Infrastructure/BotSharp.Core/MCP/McpPlugin.cs @@ -1,13 +1,10 @@ using BotSharp.Abstraction.Functions; -using BotSharp.Abstraction.Plugins; -using BotSharp.Plugin.Mcp.Functions; -using BotSharp.Plugin.Mcp.Settings; +using BotSharp.Core.Mcp.Functions; +using BotSharp.Core.Mcp.Settings; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -namespace BotSharp.Plugin.Mcp; +namespace BotSharp.Core.Mcp; public class McpPlugin : IBotSharpPlugin { diff --git a/src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs b/src/Infrastructure/BotSharp.Core/MCP/Settings/MCPSettings.cs similarity index 74% rename from src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs rename to src/Infrastructure/BotSharp.Core/MCP/Settings/MCPSettings.cs index a57050d5..6b3c4c5b 100644 --- a/src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs +++ b/src/Infrastructure/BotSharp.Core/MCP/Settings/MCPSettings.cs @@ -1,8 +1,7 @@ using McpDotNet.Client; using McpDotNet.Configuration; -using System.Collections.Generic; -namespace BotSharp.Plugin.Mcp.Settings; +namespace BotSharp.Core.Mcp.Settings; public class MCPSettings { diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index d7a6d121..eeee97d2 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -60,6 +60,9 @@ namespace BotSharp.Core.Repository case AgentField.Utility: UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; + case AgentField.Mcp: + UpdateAgentMcp(agent.Id, agent.Mcps); + break; case AgentField.KnowledgeBase: UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases); break; @@ -191,6 +194,20 @@ namespace BotSharp.Core.Repository File.WriteAllText(agentFile, json); } + private void UpdateAgentMcp(string agentId, List mcps) + { + if (mcps == null) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + + agent.Mcps = mcps; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } + private void UpdateAgentKnowledgeBases(string agentId, List knowledgeBases) { if (knowledgeBases == null) return; @@ -360,6 +377,7 @@ namespace BotSharp.Core.Repository agent.Profiles = inputAgent.Profiles; agent.Labels = inputAgent.Labels; agent.Utilities = inputAgent.Utilities; + agent.Mcps = inputAgent.Mcps; agent.KnowledgeBases = inputAgent.KnowledgeBases; agent.RoutingRules = inputAgent.RoutingRules; agent.Rules = inputAgent.Rules; diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs index 8e4d915d..e8af9018 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -55,6 +55,7 @@ public class AgentCreationModel public int? MaxMessageCount { get; set; } public List Utilities { get; set; } = new(); + public List Mcps { get; set; } = new(); public List RoutingRules { get; set; } = new(); public List KnowledgeBases { get; set; } = new(); public List Rules { get; set; } = new(); @@ -73,6 +74,7 @@ public class AgentCreationModel Responses = Responses, Samples = Samples, Utilities = Utilities, + Mcps = Mcps, IsPublic = IsPublic, Type = Type, Disabled = Disabled, diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs index ac2749b5..be2e2a36 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -39,6 +39,11 @@ public class AgentUpdateModel /// public List? Utilities { get; set; } + /// + /// Mcps + /// + public List? Mcps { get; set; } + /// /// knowledge bases /// @@ -103,6 +108,7 @@ public class AgentUpdateModel Functions = Functions ?? [], Responses = Responses ?? [], Utilities = Utilities ?? [], + Mcps = Mcps ?? [], KnowledgeBases = KnowledgeBases ?? [], Rules = Rules ?? [], LlmConfig = LlmConfig ?? new() diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index b4ba1e08..54109da6 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -24,6 +24,7 @@ public class AgentViewModel [JsonPropertyName("merge_utility")] public bool MergeUtility { get; set; } public List Utilities { get; set; } + public List Mcps { get; set; } [JsonPropertyName("knowledge_bases")] public List KnowledgeBases { get; set; } @@ -86,6 +87,7 @@ public class AgentViewModel Responses = agent.Responses ?? [], Samples = agent.Samples ?? [], Utilities = agent.Utilities ?? [], + Mcps = agent.Mcps ?? [], KnowledgeBases = agent.KnowledgeBases ?? [], IsPublic= agent.IsPublic, Disabled = agent.Disabled, diff --git a/src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj b/src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj deleted file mode 100644 index 13417a59..00000000 --- a/src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - $(TargetFramework) - enable - $(LangVersion) - $(BotSharpVersion) - $(GeneratePackageOnBuild) - $(GenerateDocumentationFile) - $(SolutionDir)packages - - - - - - - - - - - - diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs index 8457bfce..f6b82dd8 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs @@ -18,6 +18,7 @@ public class AgentDocument : MongoBase public List Responses { get; set; } public List Samples { get; set; } public List Utilities { get; set; } + public List Mcps { get; set; } public List KnowledgeBases { get; set; } public List Profiles { get; set; } public List Labels { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMcpMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMcpMongoElement.cs new file mode 100644 index 00000000..5090e1ba --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMcpMongoElement.cs @@ -0,0 +1,73 @@ +using BotSharp.Abstraction.Agents.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BotSharp.Plugin.MongoStorage.Models; + +[BsonIgnoreExtraElements(Inherited = true)] +public class AgentMcpMongoElement +{ + public string Name { get; set; } + + public string ServerId { get; set; } + + public bool Disabled { get; set; } + public List Functions { get; set; } = []; + public List Templates { get; set; } = []; + + public static AgentMcpMongoElement ToMongoElement(AgentMCP utility) + { + return new AgentMcpMongoElement + { + Name = utility.Name, + Disabled = utility.Disabled, + Functions = utility.Functions?.Select(x => new McpFunctionMongoElement(x.Name))?.ToList() ?? [], + Templates = utility.Templates?.Select(x => new McpTemplateMongoElement(x.Name))?.ToList() ?? [] + }; + } + + public static AgentMCP ToDomainElement(AgentMcpMongoElement utility) + { + return new AgentMCP + { + Name = utility.Name, + Disabled = utility.Disabled, + Functions = utility.Functions?.Select(x => new MCPFunction(x.Name))?.ToList() ?? [], + Templates = utility.Templates?.Select(x => new MCPTemplate(x.Name))?.ToList() ?? [] + }; + } +} + +public class McpFunctionMongoElement +{ + public string Name { get; set; } + + public McpFunctionMongoElement() + { + + } + + public McpFunctionMongoElement(string name) + { + Name = name; + } +} + +public class McpTemplateMongoElement +{ + public string Name { get; set; } + + public McpTemplateMongoElement() + { + + } + + public McpTemplateMongoElement(string name) + { + Name = name; + } +} + diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs index 90dd9cdf..68aa17a9 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -61,6 +61,9 @@ public partial class MongoRepository case AgentField.Utility: UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; + case AgentField.Mcp: + UpdateAgentMcps(agent.Id, agent.Mcps); + break; case AgentField.KnowledgeBase: UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases); break; @@ -261,6 +264,19 @@ public partial class MongoRepository _dc.Agents.UpdateOne(filter, update); } + private void UpdateAgentMcps(string agentId, List mcps) + { + if (mcps == null) return; + + var elements = mcps?.Select(x => AgentMcpMongoElement.ToMongoElement(x))?.ToList() ?? []; + + var filter = Builders.Filter.Eq(x => x.Id, agentId); + var update = Builders.Update + .Set(x => x.Mcps, elements) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } private void UpdateAgentKnowledgeBases(string agentId, List knowledgeBases) { if (knowledgeBases == null) return; @@ -330,6 +346,7 @@ public partial class MongoRepository .Set(x => x.Responses, agent.Responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList()) .Set(x => x.Samples, agent.Samples) .Set(x => x.Utilities, agent.Utilities.Select(u => AgentUtilityMongoElement.ToMongoElement(u)).ToList()) + .Set(x => x.Mcps, agent.Mcps.Select(u => AgentMcpMongoElement.ToMongoElement(u)).ToList()) .Set(x => x.KnowledgeBases, agent.KnowledgeBases.Select(u => AgentKnowledgeBaseMongoElement.ToMongoElement(u)).ToList()) .Set(x => x.Rules, agent.Rules.Select(e => AgentRuleMongoElement.ToMongoElement(e)).ToList()) .Set(x => x.LlmConfig, AgentLlmConfigMongoElement.ToMongoElement(agent.LlmConfig)) @@ -510,6 +527,7 @@ public partial class MongoRepository Responses = x.Responses?.Select(r => AgentResponseMongoElement.ToMongoElement(r))?.ToList() ?? [], RoutingRules = x.RoutingRules?.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?.ToList() ?? [], Utilities = x.Utilities?.Select(u => AgentUtilityMongoElement.ToMongoElement(u))?.ToList() ?? [], + Mcps = x.Mcps?.Select(u => AgentMcpMongoElement.ToMongoElement(u))?.ToList() ?? [], KnowledgeBases = x.KnowledgeBases?.Select(k => AgentKnowledgeBaseMongoElement.ToMongoElement(k))?.ToList() ?? [], Rules = x.Rules?.Select(e => AgentRuleMongoElement.ToMongoElement(e))?.ToList() ?? [], CreatedTime = x.CreatedDateTime, @@ -604,6 +622,7 @@ public partial class MongoRepository Responses = agentDoc.Responses?.Select(r => AgentResponseMongoElement.ToDomainElement(r))?.ToList() ?? [], RoutingRules = agentDoc.RoutingRules?.Select(r => RoutingRuleMongoElement.ToDomainElement(agentDoc.Id, agentDoc.Name, r))?.ToList() ?? [], Utilities = agentDoc.Utilities?.Select(u => AgentUtilityMongoElement.ToDomainElement(u))?.ToList() ?? [], + Mcps = agentDoc.Mcps?.Select(u => AgentMcpMongoElement.ToDomainElement(u))?.ToList() ?? [], KnowledgeBases = agentDoc.KnowledgeBases?.Select(x => AgentKnowledgeBaseMongoElement.ToDomainElement(x))?.ToList() ?? [], Rules = agentDoc.Rules?.Select(e => AgentRuleMongoElement.ToDomainElement(e))?.ToList() ?? [] };