From 739f2a54faf113720270e3820b885132c1501708 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Sun, 23 Feb 2025 19:45:05 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat=EF=BC=9AIntegrated=20model=20context?= =?UTF-8?q?=20protocol=EF=BC=88mcp=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BotSharp.sln | 14 +++ .../BotSharp.Plugin.Mcp.csproj | 22 +++++ .../Functions/McpAIFunction.cs | 96 +++++++++++++++++++ .../BotSharp.Plugin.Mcp/MCPClientManager.cs | 33 +++++++ src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs | 45 +++++++++ .../Settings/MCPSettings.cs | 13 +++ src/WebStarter/appsettings.json | 16 ++++ 7 files changed, 239 insertions(+) create mode 100644 src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj create mode 100644 src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs create mode 100644 src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs create mode 100644 src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs create mode 100644 src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs diff --git a/BotSharp.sln b/BotSharp.sln index d4890be1..d8796f8a 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -127,6 +127,10 @@ 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 @@ -519,6 +523,14 @@ 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 @@ -580,6 +592,8 @@ 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/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj b/src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj new file mode 100644 index 00000000..13417a59 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Mcp/BotSharp.Plugin.Mcp.csproj @@ -0,0 +1,22 @@ + + + + $(TargetFramework) + enable + $(LangVersion) + $(BotSharpVersion) + $(GeneratePackageOnBuild) + $(GenerateDocumentationFile) + $(SolutionDir)packages + + + + + + + + + + + + diff --git a/src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs b/src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs new file mode 100644 index 00000000..d19ca1e9 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Mcp/Functions/McpAIFunction.cs @@ -0,0 +1,96 @@ +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; + +public class McpAIFunction : IFunctionCallback +{ + private readonly Tool _tool; + private readonly IMcpClient _client; + + public McpAIFunction(Tool tool, IMcpClient client) + { + _tool = tool ?? throw new ArgumentNullException(nameof(tool)); + _client = client ?? throw new ArgumentNullException(nameof(client)); + } + + public string Name => _tool.Name; + + public async Task Execute(RoleDialogModel message) + { + // Convert arguments to dictionary format expected by mcpdotnet + Dictionary argDict = JsonToDictionary(message.FunctionArgs); + + // Call the tool through mcpdotnet + var result = await _client.CallToolAsync( + _tool.Name, + argDict.Count == 0 ? new() : argDict + ); + + // Extract the text content from the result + // For simplicity in this sample, we'll just concatenate all text content + message.Content = string.Join("\n", result.Content + .Where(c => c.Type == "text") + .Select(c => c.Text)); + return true; + } + + private static Dictionary JsonToDictionary(string? json) + { + if (string.IsNullOrEmpty(json)) + return []; + + // 使用JsonDocument解析JSON字符串 + using JsonDocument doc = JsonDocument.Parse(json); + JsonElement root = doc.RootElement; + return JsonElementToDictionary(root); + } + + private static Dictionary JsonElementToDictionary(JsonElement element) + { + Dictionary dictionary = []; + + if (element.ValueKind == JsonValueKind.Object) + { + foreach (JsonProperty property in element.EnumerateObject()) + { + dictionary[property.Name] = JsonElementToValue(property.Value); + } + } + + return dictionary; + } + + private static object? JsonElementToValue(JsonElement element) => element.ValueKind switch + { + JsonValueKind.Object => JsonElementToDictionary(element), + JsonValueKind.Array => element.EnumerateArray().Select(JsonElementToValue).ToList(), + JsonValueKind.String => element.GetString(), + JsonValueKind.Number when element.TryGetInt32(out int intValue) => intValue, + JsonValueKind.Number when element.TryGetInt64(out long longValue) => longValue, + JsonValueKind.Number when element.TryGetDouble(out double doubleValue) => doubleValue, + JsonValueKind.Number when element.TryGetDecimal(out decimal decimalValue) => decimalValue, + JsonValueKind.Number when element.TryGetByte(out byte byteValue) => byteValue, + JsonValueKind.Number when element.TryGetSByte(out sbyte sbyteValue) => sbyteValue, + JsonValueKind.Number when element.TryGetUInt16(out ushort uint16Value) => uint16Value, + JsonValueKind.Number when element.TryGetUInt32(out uint uint32Value) => uint32Value, + JsonValueKind.Number when element.TryGetUInt64(out ulong uint64Value) => uint64Value, + JsonValueKind.Number when element.TryGetDateTime(out DateTime dateTimeValue) => dateTimeValue, + JsonValueKind.Number when element.TryGetDateTimeOffset(out DateTimeOffset dateTimeOffsetValue) => dateTimeOffsetValue, + JsonValueKind.Number when element.TryGetGuid(out Guid guidValue) => guidValue, + JsonValueKind.Number => element.GetRawText(), + JsonValueKind.True => true, + JsonValueKind.False => false, + JsonValueKind.Null => null, + JsonValueKind.Undefined => string.Empty, // JsonElement is undefined (there is no value). + _ => throw new ArgumentOutOfRangeException(nameof(element.ValueKind), element.ValueKind, "Unexpected JsonValueKind encountered.") + }; + +} diff --git a/src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs b/src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs new file mode 100644 index 00000000..e1f01f14 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Mcp/MCPClientManager.cs @@ -0,0 +1,33 @@ +using BotSharp.Plugin.Mcp.Settings; +using McpDotNet.Client; +using Microsoft.Extensions.Logging; +using System; + +namespace BotSharp.Plugin.Mcp; + +public class MCPClientManager : IDisposable +{ + public ILoggerFactory LoggerFactory { get; } + public McpClientFactory Factory { get; } + + + private readonly MCPSettings mcpSettings; + + public MCPClientManager(MCPSettings settings, ILoggerFactory loggerFactory) + { + mcpSettings = settings; + LoggerFactory = loggerFactory; + + // Inject the mock transport into the factory + Factory = new McpClientFactory( + settings.McpServerConfigs, + settings.McpClientOptions, + LoggerFactory + ); + } + + public void Dispose() + { + LoggerFactory?.Dispose(); + } +} diff --git a/src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs b/src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs new file mode 100644 index 00000000..2bfda270 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Mcp/McpPlugin.cs @@ -0,0 +1,45 @@ +using BotSharp.Abstraction.Functions; +using BotSharp.Abstraction.Plugins; +using BotSharp.Plugin.Mcp.Functions; +using BotSharp.Plugin.Mcp.Settings; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +namespace BotSharp.Plugin.Mcp; + +public class McpPlugin : IBotSharpPlugin +{ + public string Id => "5d779611-0012-46cb-a754-4ca4770e88ac"; + public string Name => "MCP Plugin"; + public string Description => "Integrated MCP tools"; + + private MCPClientManager clientManager; + + public void RegisterDI(IServiceCollection services, IConfiguration config) + { + var settings = config.GetSection("MCPSettings").Get(); + services.AddScoped(provider => { return settings; }); + services.AddSingleton(provider => + { + var loggerFactory = provider.GetService() ?? NullLoggerFactory.Instance; + return new MCPClientManager(settings, loggerFactory); + }); + + foreach (var server in settings.McpServerConfigs) + { + var client = clientManager.Factory.GetClientAsync(server.Id).Result; + var tools = client.ListToolsAsync().Result; + + foreach (var tool in tools.Tools) + { + services.AddScoped(provider => + { + var func = new McpAIFunction(tool, client); + return func; + }); + } + } + } + } diff --git a/src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs b/src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs new file mode 100644 index 00000000..a57050d5 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Mcp/Settings/MCPSettings.cs @@ -0,0 +1,13 @@ +using McpDotNet.Client; +using McpDotNet.Configuration; +using System.Collections.Generic; + +namespace BotSharp.Plugin.Mcp.Settings; + +public class MCPSettings +{ + public McpClientOptions McpClientOptions { get; set; } + + public List McpServerConfigs { get; set; } + +} diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 655fa954..7b19e043 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -175,6 +175,22 @@ } }, + "McpClientOptions": { + "ClientInfo": { + "Name": "SimpleToolsBotsharp", + "Version": "1.0.0" + } + }, + "McpServerOptions": [ + { + "Id": "everything", + "Name": "Everything", + "TransportType": "sse", + "TransportOptions": {}, + "Location": "http://localhost:5000/sse" + } + ] + }, "Conversation": { "DataDir": "conversations", "ShowVerboseLog": false, From ddecb4d19a8fd704de7553a1cd269f2ca1d5ce4f Mon Sep 17 00:00:00 2001 From: geffzhang Date: Sun, 23 Feb 2025 19:45:22 +0800 Subject: [PATCH 2/5] Update appsettings.json --- src/WebStarter/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 7b19e043..21c2f0b5 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -174,7 +174,7 @@ "Model": "gpt-4o-mini" } }, - + "MCPSettings": { "McpClientOptions": { "ClientInfo": { "Name": "SimpleToolsBotsharp", From 9b662168ff3b09daa7882dbf8b73956d56281c63 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Sun, 23 Feb 2025 22:55:35 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat=20=EF=BC=9A=20Agent=20add=20mcp=20prop?= =?UTF-8?q?erty?= 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() ?? [] }; From 731355d1101bba477158ad7b92c425d58b060460 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Mon, 24 Feb 2025 09:04:44 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat=EF=BC=9A=20Rename=20Agent=20Context=20?= =?UTF-8?q?Protocols?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Agents/AgentHookBase.cs | 2 +- .../Agents/Enums/AgentField.cs | 2 +- .../BotSharp.Abstraction/Agents/IAgentHook.cs | 2 +- .../Agents/Models/Agent.cs | 8 ++--- .../Agents/Models/{AgentMCP.cs => AgentCP.cs} | 26 +++++++------- .../Agents/Hooks/BasicAgentHook.cs | 10 +++--- .../Agents/Services/AgentService.LoadAgent.cs | 4 +-- .../Services/AgentService.UpdateAgent.cs | 4 +-- .../FileRepository/FileRepository.Agent.cs | 10 +++--- .../ViewModels/Agents/AgentCreationModel.cs | 4 +-- .../ViewModels/Agents/AgentUpdateModel.cs | 6 ++-- .../ViewModels/Agents/AgentViewModel.cs | 4 +-- .../Collections/AgentDocument.cs | 2 +- ...MongoElement.cs => AgentCPMongoElement.cs} | 34 +++++++++---------- .../Repository/MongoRepository.Agent.cs | 14 ++++---- 15 files changed, 66 insertions(+), 66 deletions(-) rename src/Infrastructure/BotSharp.Abstraction/Agents/Models/{AgentMCP.cs => AgentCP.cs} (54%) rename src/Plugins/BotSharp.Plugin.MongoStorage/Models/{AgentMcpMongoElement.cs => AgentCPMongoElement.cs} (51%) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs index ff52bb46..295d3bc2 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs @@ -60,7 +60,7 @@ public abstract class AgentHookBase : IAgentHook } - public virtual void OnAgentMCPLoaded(Agent agent) + public virtual void OnAgentCPLoaded(Agent agent) { } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs index e02d02d7..413f9eb8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs @@ -19,7 +19,7 @@ public enum AgentField Sample, LlmConfig, Utility, - Mcp, + Acp, KnowledgeBase, Rule, MaxMessageCount diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs index 21bf8b5b..59920408 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs @@ -27,7 +27,7 @@ public interface IAgentHook void OnAgentUtilityLoaded(Agent agent); - void OnAgentMCPLoaded(Agent agent); + void OnAgentCPLoaded(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 bed77d43..da57d33b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -106,7 +106,7 @@ public class Agent /// /// Agent MCP /// - public List Mcps { get; set; } = new(); + public List Acps { get; set; } = new(); /// /// Agent rules @@ -161,7 +161,7 @@ public class Agent Responses = agent.Responses, Samples = agent.Samples, Utilities = agent.Utilities, - Mcps = agent.Mcps, + Acps = agent.Acps, Knowledges = agent.Knowledges, IsPublic = agent.IsPublic, Disabled = agent.Disabled, @@ -304,9 +304,9 @@ public class Agent return this; } - public Agent SetMcps(List mcps) + public Agent SetMcps(List mcps) { - Mcps = mcps ?? []; + Acps = mcps ?? []; return this; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs similarity index 54% rename from src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs rename to src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs index 98a186dc..735e7dc8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentMCP.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs @@ -1,6 +1,6 @@ namespace BotSharp.Abstraction.Agents.Models; -public class AgentMCP +public class AgentCP { public string Name { get; set; } @@ -8,18 +8,18 @@ public class AgentMCP public bool Disabled { get; set; } - public IEnumerable Functions { get; set; } = []; - public IEnumerable Templates { get; set; } = []; + public IEnumerable Functions { get; set; } = []; + public IEnumerable Templates { get; set; } = []; - public AgentMCP() + public AgentCP() { } - public AgentMCP( + public AgentCP( string name, - IEnumerable? functions = null, - IEnumerable? templates = null) + IEnumerable? functions = null, + IEnumerable? templates = null) { Name = name; Functions = functions ?? []; @@ -33,27 +33,27 @@ public class AgentMCP } -public class MCPFunction : MCPBase +public class ACPFunction : MCPBase { - public MCPFunction() + public ACPFunction() { } - public MCPFunction(string name) + public ACPFunction(string name) { Name = name; } } -public class MCPTemplate : MCPBase +public class ACPTemplate : MCPBase { - public MCPTemplate() + public ACPTemplate() { } - public MCPTemplate(string name) + public ACPTemplate(string name) { Name = name; } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs index b3bf3868..bcb15bd3 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs @@ -42,7 +42,7 @@ public class BasicAgentHook : AgentHookBase } } - public override void OnAgentMCPLoaded(Agent agent) + public override void OnAgentCPLoaded(Agent agent) { if (agent.Type == AgentType.Routing) return; @@ -53,9 +53,9 @@ public class BasicAgentHook : AgentHookBase agent.SecondaryFunctions ??= []; agent.SecondaryInstructions ??= []; - agent.Mcps ??= []; + agent.Acps ??= []; - var (functions, templates) = GetMCPContent(agent); + var (functions, templates) = GetACPContent(agent); foreach (var fn in functions) { @@ -116,12 +116,12 @@ public class BasicAgentHook : AgentHookBase return (functionNames, templateNames); } - private (IEnumerable, IEnumerable) GetMCPContent(Agent agent) + private (IEnumerable, IEnumerable) GetACPContent(Agent agent) { List functionDefs = new List(); IEnumerable templates = new List(); var mcpClientManager = _services.GetRequiredService(); - var mcps = agent.Mcps; + var mcps = agent.Acps; foreach (var item in mcps) { var ua = mcpClientManager.Factory.GetClientAsync(item.ServerId).Result; diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs index 411c2e89..70722c6a 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs @@ -72,9 +72,9 @@ public partial class AgentService hook.OnAgentUtilityLoaded(agent); } - if(agent.Mcps != null) + if(agent.Acps != null) { - hook.OnAgentMCPLoaded(agent); + hook.OnAgentCPLoaded(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 8fdb2c9b..30a621c4 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -40,7 +40,7 @@ public partial class AgentService record.Responses = agent.Responses ?? []; record.Samples = agent.Samples ?? []; record.Utilities = agent.Utilities ?? []; - record.Mcps = agent.Mcps ?? []; + record.Acps = agent.Acps ?? []; record.KnowledgeBases = agent.KnowledgeBases ?? []; record.Rules = agent.Rules ?? []; if (agent.LlmConfig != null && !agent.LlmConfig.IsInherit) @@ -107,7 +107,7 @@ public partial class AgentService .SetResponses(foundAgent.Responses) .SetSamples(foundAgent.Samples) .SetUtilities(foundAgent.Utilities) - .SetMcps(foundAgent.Mcps) + .SetMcps(foundAgent.Acps) .SetKnowledgeBases(foundAgent.KnowledgeBases) .SetRules(foundAgent.Rules) .SetLlmConfig(foundAgent.LlmConfig); diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index eeee97d2..8b7b547a 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -60,8 +60,8 @@ namespace BotSharp.Core.Repository case AgentField.Utility: UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; - case AgentField.Mcp: - UpdateAgentMcp(agent.Id, agent.Mcps); + case AgentField.Acp: + UpdateAgentCP(agent.Id, agent.Acps); break; case AgentField.KnowledgeBase: UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases); @@ -194,7 +194,7 @@ namespace BotSharp.Core.Repository File.WriteAllText(agentFile, json); } - private void UpdateAgentMcp(string agentId, List mcps) + private void UpdateAgentCP(string agentId, List mcps) { if (mcps == null) return; @@ -202,7 +202,7 @@ namespace BotSharp.Core.Repository if (agent == null) return; - agent.Mcps = mcps; + agent.Acps = mcps; agent.UpdatedDateTime = DateTime.UtcNow; var json = JsonSerializer.Serialize(agent, _options); File.WriteAllText(agentFile, json); @@ -377,7 +377,7 @@ namespace BotSharp.Core.Repository agent.Profiles = inputAgent.Profiles; agent.Labels = inputAgent.Labels; agent.Utilities = inputAgent.Utilities; - agent.Mcps = inputAgent.Mcps; + agent.Acps = inputAgent.Acps; 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 e8af9018..6432b355 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -55,7 +55,7 @@ public class AgentCreationModel public int? MaxMessageCount { get; set; } public List Utilities { get; set; } = new(); - public List Mcps { get; set; } = new(); + public List Acps { get; set; } = new(); public List RoutingRules { get; set; } = new(); public List KnowledgeBases { get; set; } = new(); public List Rules { get; set; } = new(); @@ -74,7 +74,7 @@ public class AgentCreationModel Responses = Responses, Samples = Samples, Utilities = Utilities, - Mcps = Mcps, + Acps = Acps, 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 be2e2a36..c5295891 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -40,9 +40,9 @@ public class AgentUpdateModel public List? Utilities { get; set; } /// - /// Mcps + /// Acps /// - public List? Mcps { get; set; } + public List? Acps { get; set; } /// /// knowledge bases @@ -108,7 +108,7 @@ public class AgentUpdateModel Functions = Functions ?? [], Responses = Responses ?? [], Utilities = Utilities ?? [], - Mcps = Mcps ?? [], + Acps = Acps ?? [], 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 54109da6..934322cb 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -24,7 +24,7 @@ public class AgentViewModel [JsonPropertyName("merge_utility")] public bool MergeUtility { get; set; } public List Utilities { get; set; } - public List Mcps { get; set; } + public List Acps { get; set; } [JsonPropertyName("knowledge_bases")] public List KnowledgeBases { get; set; } @@ -87,7 +87,7 @@ public class AgentViewModel Responses = agent.Responses ?? [], Samples = agent.Samples ?? [], Utilities = agent.Utilities ?? [], - Mcps = agent.Mcps ?? [], + Acps = agent.Acps ?? [], KnowledgeBases = agent.KnowledgeBases ?? [], IsPublic= agent.IsPublic, Disabled = agent.Disabled, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs index f6b82dd8..6be40cf6 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs @@ -18,7 +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 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/AgentCPMongoElement.cs similarity index 51% rename from src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMcpMongoElement.cs rename to src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentCPMongoElement.cs index 5090e1ba..eb149736 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMcpMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentCPMongoElement.cs @@ -8,64 +8,64 @@ using System.Threading.Tasks; namespace BotSharp.Plugin.MongoStorage.Models; [BsonIgnoreExtraElements(Inherited = true)] -public class AgentMcpMongoElement +public class AgentCPMongoElement { 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 List Functions { get; set; } = []; + public List Templates { get; set; } = []; - public static AgentMcpMongoElement ToMongoElement(AgentMCP utility) + public static AgentCPMongoElement ToMongoElement(AgentCP utility) { - return new AgentMcpMongoElement + return new AgentCPMongoElement { 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() ?? [] + Functions = utility.Functions?.Select(x => new AcpFunctionMongoElement(x.Name))?.ToList() ?? [], + Templates = utility.Templates?.Select(x => new AcpTemplateMongoElement(x.Name))?.ToList() ?? [] }; } - public static AgentMCP ToDomainElement(AgentMcpMongoElement utility) + public static AgentCP ToDomainElement(AgentCPMongoElement utility) { - return new AgentMCP + return new AgentCP { 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() ?? [] + Functions = utility.Functions?.Select(x => new ACPFunction(x.Name))?.ToList() ?? [], + Templates = utility.Templates?.Select(x => new ACPTemplate(x.Name))?.ToList() ?? [] }; } } -public class McpFunctionMongoElement +public class AcpFunctionMongoElement { public string Name { get; set; } - public McpFunctionMongoElement() + public AcpFunctionMongoElement() { } - public McpFunctionMongoElement(string name) + public AcpFunctionMongoElement(string name) { Name = name; } } -public class McpTemplateMongoElement +public class AcpTemplateMongoElement { public string Name { get; set; } - public McpTemplateMongoElement() + public AcpTemplateMongoElement() { } - public McpTemplateMongoElement(string name) + public AcpTemplateMongoElement(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 68aa17a9..98fee01a 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -61,8 +61,8 @@ public partial class MongoRepository case AgentField.Utility: UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; - case AgentField.Mcp: - UpdateAgentMcps(agent.Id, agent.Mcps); + case AgentField.Acp: + UpdateAgentMcps(agent.Id, agent.Acps); break; case AgentField.KnowledgeBase: UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases); @@ -264,11 +264,11 @@ public partial class MongoRepository _dc.Agents.UpdateOne(filter, update); } - private void UpdateAgentMcps(string agentId, List mcps) + private void UpdateAgentMcps(string agentId, List mcps) { if (mcps == null) return; - var elements = mcps?.Select(x => AgentMcpMongoElement.ToMongoElement(x))?.ToList() ?? []; + var elements = mcps?.Select(x => AgentCPMongoElement.ToMongoElement(x))?.ToList() ?? []; var filter = Builders.Filter.Eq(x => x.Id, agentId); var update = Builders.Update @@ -346,7 +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.Mcps, agent.Acps.Select(u => AgentCPMongoElement.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)) @@ -527,7 +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() ?? [], + Mcps = x.Acps?.Select(u => AgentCPMongoElement.ToMongoElement(u))?.ToList() ?? [], KnowledgeBases = x.KnowledgeBases?.Select(k => AgentKnowledgeBaseMongoElement.ToMongoElement(k))?.ToList() ?? [], Rules = x.Rules?.Select(e => AgentRuleMongoElement.ToMongoElement(e))?.ToList() ?? [], CreatedTime = x.CreatedDateTime, @@ -622,7 +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() ?? [], + Acps = agentDoc.Mcps?.Select(u => AgentCPMongoElement.ToDomainElement(u))?.ToList() ?? [], KnowledgeBases = agentDoc.KnowledgeBases?.Select(x => AgentKnowledgeBaseMongoElement.ToDomainElement(x))?.ToList() ?? [], Rules = agentDoc.Rules?.Select(e => AgentRuleMongoElement.ToDomainElement(e))?.ToList() ?? [] }; From 69993bdca82f61f190930c0d3c069a9ed4545d98 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Tue, 25 Feb 2025 22:57:22 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat=EF=BC=9AMigrate=20MCP=20to=20the=20ind?= =?UTF-8?q?ependent=20BotSharp.MCP=20package?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BotSharp.sln | 11 +++ .../Agents/AgentHookBase.cs | 2 +- .../BotSharp.Abstraction/Agents/IAgentHook.cs | 2 +- .../Agents/Models/Agent.cs | 15 ++-- .../Agents/Models/AgentCP.cs | 65 ----------------- .../Agents/Models/MCPTool.cs | 41 +++++++++++ .../Agents/Hooks/BasicAgentHook.cs | 61 +--------------- .../Agents/Services/AgentService.LoadAgent.cs | 4 +- .../Services/AgentService.UpdateAgent.cs | 4 +- .../BotSharp.Core/BotSharp.Core.csproj | 1 - .../FileRepository/FileRepository.Agent.cs | 10 +-- .../AIFunctionUtilities.cs | 1 + .../BotSharp.MCP/BotSharp.MCP.csproj | 18 +++++ .../Functions/McpToolFunction.cs} | 10 ++- .../BotSharp.MCP/Hooks/MCPToolAgentHook.cs | 71 +++++++++++++++++++ .../MCP => BotSharp.MCP}/MCPClientManager.cs | 2 + .../MCP => BotSharp.MCP}/McpPlugin.cs | 5 +- .../Settings/MCPSettings.cs | 1 + .../ViewModels/Agents/AgentCreationModel.cs | 4 +- .../ViewModels/Agents/AgentUpdateModel.cs | 6 +- .../ViewModels/Agents/AgentViewModel.cs | 4 +- .../Collections/AgentDocument.cs | 2 +- ...Element.cs => AgentMCPToolMongoElement.cs} | 32 ++++----- .../Repository/MongoRepository.Agent.cs | 14 ++-- 24 files changed, 209 insertions(+), 177 deletions(-) delete mode 100644 src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Agents/Models/MCPTool.cs rename src/Infrastructure/{BotSharp.Core/MCP => BotSharp.MCP}/AIFunctionUtilities.cs (95%) create mode 100644 src/Infrastructure/BotSharp.MCP/BotSharp.MCP.csproj rename src/Infrastructure/{BotSharp.Core/MCP/Functions/McpAIFunction.cs => BotSharp.MCP/Functions/McpToolFunction.cs} (93%) create mode 100644 src/Infrastructure/BotSharp.MCP/Hooks/MCPToolAgentHook.cs rename src/Infrastructure/{BotSharp.Core/MCP => BotSharp.MCP}/MCPClientManager.cs (93%) rename src/Infrastructure/{BotSharp.Core/MCP => BotSharp.MCP}/McpPlugin.cs (88%) rename src/Infrastructure/{BotSharp.Core/MCP => BotSharp.MCP}/Settings/MCPSettings.cs (87%) rename src/Plugins/BotSharp.Plugin.MongoStorage/Models/{AgentCPMongoElement.cs => AgentMCPToolMongoElement.cs} (54%) diff --git a/BotSharp.sln b/BotSharp.sln index d4890be1..d82f930c 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -127,6 +127,8 @@ 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("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.MCP", "src\Infrastructure\BotSharp.MCP\BotSharp.MCP.csproj", "{8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -519,6 +521,14 @@ 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 + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Debug|x64.ActiveCfg = Debug|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Debug|x64.Build.0 = Debug|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Release|Any CPU.Build.0 = Release|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Release|x64.ActiveCfg = Release|Any CPU + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -580,6 +590,7 @@ 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} + {8ED8EEF4-06DD-45F5-AA91-BD2395E901B5} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749} 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 295d3bc2..1103f2f5 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs @@ -60,7 +60,7 @@ public abstract class AgentHookBase : IAgentHook } - public virtual void OnAgentCPLoaded(Agent agent) + public virtual void OnAgentMCPToolLoaded(Agent agent) { } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs index 59920408..624616d7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs @@ -27,7 +27,7 @@ public interface IAgentHook void OnAgentUtilityLoaded(Agent agent); - void OnAgentCPLoaded(Agent agent); + void OnAgentMCPToolLoaded(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 da57d33b..fc28e571 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -95,18 +95,19 @@ public class Agent public List Labels { get; set; } = new(); /// - /// Merge mcps from entry agent + /// Merge Utility from entry agent /// public bool MergeUtility { get; set; } /// - /// Agent mcps + /// Agent Utility /// public List Utilities { get; set; } = new(); + /// - /// Agent MCP + /// Agent MCP Tools /// - public List Acps { get; set; } = new(); + public List McpTools { get; set; } = new(); /// /// Agent rules @@ -161,7 +162,7 @@ public class Agent Responses = agent.Responses, Samples = agent.Samples, Utilities = agent.Utilities, - Acps = agent.Acps, + McpTools = agent.McpTools, Knowledges = agent.Knowledges, IsPublic = agent.IsPublic, Disabled = agent.Disabled, @@ -304,9 +305,9 @@ public class Agent return this; } - public Agent SetMcps(List mcps) + public Agent SetMcps(List mcps) { - Acps = mcps ?? []; + McpTools = mcps ?? []; return this; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs deleted file mode 100644 index 735e7dc8..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentCP.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace BotSharp.Abstraction.Agents.Models; - -public class AgentCP -{ - 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 AgentCP() - { - - } - - public AgentCP( - string name, - IEnumerable? functions = null, - IEnumerable? templates = null) - { - Name = name; - Functions = functions ?? []; - Templates = templates ?? []; - } - - public override string ToString() - { - return Name; - } -} - - -public class ACPFunction : MCPBase -{ - public ACPFunction() - { - - } - - public ACPFunction(string name) - { - Name = name; - } -} - -public class ACPTemplate : MCPBase -{ - public ACPTemplate() - { - - } - - public ACPTemplate(string name) - { - Name = name; - } -} - -public class MCPBase -{ - public string Name { get; set; } -} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/MCPTool.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/MCPTool.cs new file mode 100644 index 00000000..fc8fbb62 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/MCPTool.cs @@ -0,0 +1,41 @@ +namespace BotSharp.Abstraction.Agents.Models; + +public class MCPTool +{ + public string Name { get; set; } + + public string ServerId { get; set; } + + public bool Disabled { get; set; } + + public IEnumerable Functions { get; set; } = []; + + public MCPTool() + { + + } + + public MCPTool( + string name, + IEnumerable? functions = null) + { + Name = name; + Functions = functions ?? []; + } + + public override string ToString() + { + return Name; + } +} + + +public class MCPFunction +{ + public string Name { get; set; } + + public MCPFunction() + { + + } +} diff --git a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs index bcb15bd3..5ab0ea03 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs @@ -1,6 +1,3 @@ -using BotSharp.Core.Mcp; -using BotSharp.Core.MCP; - namespace BotSharp.Core.Agents.Hooks; public class BasicAgentHook : AgentHookBase @@ -41,36 +38,7 @@ public class BasicAgentHook : AgentHookBase agent.SecondaryInstructions.Add(prompt); } } - - public override void OnAgentCPLoaded(Agent agent) - { - if (agent.Type == AgentType.Routing) - return; - - var conv = _services.GetRequiredService(); - var isConvMode = conv.IsConversationMode(); - if (!isConvMode) return; - - agent.SecondaryFunctions ??= []; - agent.SecondaryInstructions ??= []; - agent.Acps ??= []; - - var (functions, templates) = GetACPContent(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) { @@ -114,30 +82,5 @@ public class BasicAgentHook : AgentHookBase .Distinct().ToList(); return (functionNames, templateNames); - } - - private (IEnumerable, IEnumerable) GetACPContent(Agent agent) - { - List functionDefs = new List(); - IEnumerable templates = new List(); - var mcpClientManager = _services.GetRequiredService(); - var mcps = agent.Acps; - 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 70722c6a..7fd94340 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs @@ -72,9 +72,9 @@ public partial class AgentService hook.OnAgentUtilityLoaded(agent); } - if(agent.Acps != null) + if(agent.McpTools != null) { - hook.OnAgentCPLoaded(agent); + hook.OnAgentMCPToolLoaded(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 30a621c4..7e9da19c 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -40,7 +40,7 @@ public partial class AgentService record.Responses = agent.Responses ?? []; record.Samples = agent.Samples ?? []; record.Utilities = agent.Utilities ?? []; - record.Acps = agent.Acps ?? []; + record.McpTools = agent.McpTools ?? []; record.KnowledgeBases = agent.KnowledgeBases ?? []; record.Rules = agent.Rules ?? []; if (agent.LlmConfig != null && !agent.LlmConfig.IsInherit) @@ -107,7 +107,7 @@ public partial class AgentService .SetResponses(foundAgent.Responses) .SetSamples(foundAgent.Samples) .SetUtilities(foundAgent.Utilities) - .SetMcps(foundAgent.Acps) + .SetMcps(foundAgent.McpTools) .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 0d684675..37eee3ac 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -195,7 +195,6 @@ - diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index 8b7b547a..ae401508 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -61,7 +61,7 @@ namespace BotSharp.Core.Repository UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; case AgentField.Acp: - UpdateAgentCP(agent.Id, agent.Acps); + UpdateAgentMcpTools(agent.Id, agent.McpTools); break; case AgentField.KnowledgeBase: UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases); @@ -194,15 +194,15 @@ namespace BotSharp.Core.Repository File.WriteAllText(agentFile, json); } - private void UpdateAgentCP(string agentId, List mcps) + private void UpdateAgentMcpTools(string agentId, List mcptools) { - if (mcps == null) return; + if (mcptools == null) return; var (agent, agentFile) = GetAgentFromFile(agentId); if (agent == null) return; - agent.Acps = mcps; + agent.McpTools = mcptools; agent.UpdatedDateTime = DateTime.UtcNow; var json = JsonSerializer.Serialize(agent, _options); File.WriteAllText(agentFile, json); @@ -377,7 +377,7 @@ namespace BotSharp.Core.Repository agent.Profiles = inputAgent.Profiles; agent.Labels = inputAgent.Labels; agent.Utilities = inputAgent.Utilities; - agent.Acps = inputAgent.Acps; + agent.McpTools = inputAgent.McpTools; agent.KnowledgeBases = inputAgent.KnowledgeBases; agent.RoutingRules = inputAgent.RoutingRules; agent.Rules = inputAgent.Rules; diff --git a/src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs b/src/Infrastructure/BotSharp.MCP/AIFunctionUtilities.cs similarity index 95% rename from src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs rename to src/Infrastructure/BotSharp.MCP/AIFunctionUtilities.cs index 9c40eaa1..e86cbf92 100644 --- a/src/Infrastructure/BotSharp.Core/MCP/AIFunctionUtilities.cs +++ b/src/Infrastructure/BotSharp.MCP/AIFunctionUtilities.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Functions.Models; using McpDotNet.Protocol.Types; using System; using System.Collections.Generic; diff --git a/src/Infrastructure/BotSharp.MCP/BotSharp.MCP.csproj b/src/Infrastructure/BotSharp.MCP/BotSharp.MCP.csproj new file mode 100644 index 00000000..c171a732 --- /dev/null +++ b/src/Infrastructure/BotSharp.MCP/BotSharp.MCP.csproj @@ -0,0 +1,18 @@ + + + + $(TargetFramework) + $(LangVersion) + $(BotSharpVersion) + $(GeneratePackageOnBuild) + $(SolutionDir)packages + + + + + + + + + + diff --git a/src/Infrastructure/BotSharp.Core/MCP/Functions/McpAIFunction.cs b/src/Infrastructure/BotSharp.MCP/Functions/McpToolFunction.cs similarity index 93% rename from src/Infrastructure/BotSharp.Core/MCP/Functions/McpAIFunction.cs rename to src/Infrastructure/BotSharp.MCP/Functions/McpToolFunction.cs index b7d36b2f..5df8fb07 100644 --- a/src/Infrastructure/BotSharp.Core/MCP/Functions/McpAIFunction.cs +++ b/src/Infrastructure/BotSharp.MCP/Functions/McpToolFunction.cs @@ -1,15 +1,21 @@ +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.Core.Mcp.Functions; -public class McpAIFunction : IFunctionCallback +public class McpToolFunction : IFunctionCallback { private readonly Tool _tool; private readonly IMcpClient _client; - public McpAIFunction(Tool tool, IMcpClient client) + public McpToolFunction(Tool tool, IMcpClient client) { _tool = tool ?? throw new ArgumentNullException(nameof(tool)); _client = client ?? throw new ArgumentNullException(nameof(client)); diff --git a/src/Infrastructure/BotSharp.MCP/Hooks/MCPToolAgentHook.cs b/src/Infrastructure/BotSharp.MCP/Hooks/MCPToolAgentHook.cs new file mode 100644 index 00000000..a4ac94b7 --- /dev/null +++ b/src/Infrastructure/BotSharp.MCP/Hooks/MCPToolAgentHook.cs @@ -0,0 +1,71 @@ +using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Agents.Settings; +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Functions.Models; +using BotSharp.Core.Mcp; +using BotSharp.Core.MCP; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BotSharp.MCP.Hooks; + +public class MCPToolAgentHook : AgentHookBase +{ + public override string SelfId => string.Empty; + + public MCPToolAgentHook(IServiceProvider services, AgentSettings settings) + : base(services, settings) + { + } + + public override void OnAgentMCPToolLoaded(Agent agent) + { + if (agent.Type == AgentType.Routing) + return; + + var conv = _services.GetRequiredService(); + var isConvMode = conv.IsConversationMode(); + if (!isConvMode) return; + + agent.SecondaryFunctions ??= []; + agent.SecondaryInstructions ??= []; + agent.McpTools ??= []; + + var functions = GetMCPContent(agent); + + foreach (var fn in functions) + { + if (!agent.SecondaryFunctions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase))) + { + agent.SecondaryFunctions.Add(fn); + } + } + } + + private IEnumerable GetMCPContent(Agent agent) + { + List functionDefs = new List(); + var mcpClientManager = _services.GetRequiredService(); + var mcps = agent.McpTools; + 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; + } +} diff --git a/src/Infrastructure/BotSharp.Core/MCP/MCPClientManager.cs b/src/Infrastructure/BotSharp.MCP/MCPClientManager.cs similarity index 93% rename from src/Infrastructure/BotSharp.Core/MCP/MCPClientManager.cs rename to src/Infrastructure/BotSharp.MCP/MCPClientManager.cs index bd115942..bbe70205 100644 --- a/src/Infrastructure/BotSharp.Core/MCP/MCPClientManager.cs +++ b/src/Infrastructure/BotSharp.MCP/MCPClientManager.cs @@ -1,5 +1,7 @@ using BotSharp.Core.Mcp.Settings; using McpDotNet.Client; +using Microsoft.Extensions.Logging; +using System; namespace BotSharp.Core.Mcp; diff --git a/src/Infrastructure/BotSharp.Core/MCP/McpPlugin.cs b/src/Infrastructure/BotSharp.MCP/McpPlugin.cs similarity index 88% rename from src/Infrastructure/BotSharp.Core/MCP/McpPlugin.cs rename to src/Infrastructure/BotSharp.MCP/McpPlugin.cs index 7ab8d249..c54a7050 100644 --- a/src/Infrastructure/BotSharp.Core/MCP/McpPlugin.cs +++ b/src/Infrastructure/BotSharp.MCP/McpPlugin.cs @@ -1,7 +1,10 @@ using BotSharp.Abstraction.Functions; +using BotSharp.Abstraction.Plugins; 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.Core.Mcp; @@ -33,7 +36,7 @@ public class McpPlugin : IBotSharpPlugin { services.AddScoped(provider => { - var func = new McpAIFunction(tool, client); + var func = new McpToolFunction(tool, client); return func; }); } diff --git a/src/Infrastructure/BotSharp.Core/MCP/Settings/MCPSettings.cs b/src/Infrastructure/BotSharp.MCP/Settings/MCPSettings.cs similarity index 87% rename from src/Infrastructure/BotSharp.Core/MCP/Settings/MCPSettings.cs rename to src/Infrastructure/BotSharp.MCP/Settings/MCPSettings.cs index 6b3c4c5b..34e408e3 100644 --- a/src/Infrastructure/BotSharp.Core/MCP/Settings/MCPSettings.cs +++ b/src/Infrastructure/BotSharp.MCP/Settings/MCPSettings.cs @@ -1,5 +1,6 @@ using McpDotNet.Client; using McpDotNet.Configuration; +using System.Collections.Generic; namespace BotSharp.Core.Mcp.Settings; diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs index 6432b355..81ec1bc7 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -55,7 +55,7 @@ public class AgentCreationModel public int? MaxMessageCount { get; set; } public List Utilities { get; set; } = new(); - public List Acps { get; set; } = new(); + public List McpTools { get; set; } = new(); public List RoutingRules { get; set; } = new(); public List KnowledgeBases { get; set; } = new(); public List Rules { get; set; } = new(); @@ -74,7 +74,7 @@ public class AgentCreationModel Responses = Responses, Samples = Samples, Utilities = Utilities, - Acps = Acps, + McpTools = McpTools, 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 c5295891..9f2925e5 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -40,9 +40,9 @@ public class AgentUpdateModel public List? Utilities { get; set; } /// - /// Acps + /// McpTools /// - public List? Acps { get; set; } + public List? McpTools { get; set; } /// /// knowledge bases @@ -108,7 +108,7 @@ public class AgentUpdateModel Functions = Functions ?? [], Responses = Responses ?? [], Utilities = Utilities ?? [], - Acps = Acps ?? [], + McpTools = McpTools ?? [], 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 934322cb..db3af34c 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -24,7 +24,7 @@ public class AgentViewModel [JsonPropertyName("merge_utility")] public bool MergeUtility { get; set; } public List Utilities { get; set; } - public List Acps { get; set; } + public List Acps { get; set; } [JsonPropertyName("knowledge_bases")] public List KnowledgeBases { get; set; } @@ -87,7 +87,7 @@ public class AgentViewModel Responses = agent.Responses ?? [], Samples = agent.Samples ?? [], Utilities = agent.Utilities ?? [], - Acps = agent.Acps ?? [], + Acps = agent.McpTools ?? [], KnowledgeBases = agent.KnowledgeBases ?? [], IsPublic= agent.IsPublic, Disabled = agent.Disabled, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs index 6be40cf6..bf5330e3 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs @@ -18,7 +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 McpTools { 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/AgentCPMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMCPToolMongoElement.cs similarity index 54% rename from src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentCPMongoElement.cs rename to src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMCPToolMongoElement.cs index eb149736..dae4c665 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentCPMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentMCPToolMongoElement.cs @@ -8,64 +8,64 @@ using System.Threading.Tasks; namespace BotSharp.Plugin.MongoStorage.Models; [BsonIgnoreExtraElements(Inherited = true)] -public class AgentCPMongoElement +public class AgentMCPToolMongoElement { 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 List Functions { get; set; } = []; + public List Templates { get; set; } = []; - public static AgentCPMongoElement ToMongoElement(AgentCP utility) + public static AgentMCPToolMongoElement ToMongoElement(MCPTool utility) { - return new AgentCPMongoElement + return new AgentMCPToolMongoElement { Name = utility.Name, Disabled = utility.Disabled, - Functions = utility.Functions?.Select(x => new AcpFunctionMongoElement(x.Name))?.ToList() ?? [], - Templates = utility.Templates?.Select(x => new AcpTemplateMongoElement(x.Name))?.ToList() ?? [] + Functions = utility.Functions?.Select(x => new McpFunctionMongoElement(x.Name))?.ToList() ?? [], + Templates = utility.Templates?.Select(x => new McpTemplateMongoElement(x.Name))?.ToList() ?? [] }; } - public static AgentCP ToDomainElement(AgentCPMongoElement utility) + public static MCPTool ToDomainElement(AgentMCPToolMongoElement utility) { - return new AgentCP + return new MCPTool { Name = utility.Name, Disabled = utility.Disabled, - Functions = utility.Functions?.Select(x => new ACPFunction(x.Name))?.ToList() ?? [], + Functions = utility.Functions?.Select(x => new MCPFunction(x.Name))?.ToList() ?? [], Templates = utility.Templates?.Select(x => new ACPTemplate(x.Name))?.ToList() ?? [] }; } } -public class AcpFunctionMongoElement +public class McpFunctionMongoElement { public string Name { get; set; } - public AcpFunctionMongoElement() + public McpFunctionMongoElement() { } - public AcpFunctionMongoElement(string name) + public McpFunctionMongoElement(string name) { Name = name; } } -public class AcpTemplateMongoElement +public class McpTemplateMongoElement { public string Name { get; set; } - public AcpTemplateMongoElement() + public McpTemplateMongoElement() { } - public AcpTemplateMongoElement(string name) + 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 98fee01a..069845ef 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -62,7 +62,7 @@ public partial class MongoRepository UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities); break; case AgentField.Acp: - UpdateAgentMcps(agent.Id, agent.Acps); + UpdateAgentMcps(agent.Id, agent.McpTools); break; case AgentField.KnowledgeBase: UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases); @@ -264,15 +264,15 @@ public partial class MongoRepository _dc.Agents.UpdateOne(filter, update); } - private void UpdateAgentMcps(string agentId, List mcps) + private void UpdateAgentMcps(string agentId, List mcps) { if (mcps == null) return; - var elements = mcps?.Select(x => AgentCPMongoElement.ToMongoElement(x))?.ToList() ?? []; + var elements = mcps?.Select(x => AgentMCPToolMongoElement.ToMongoElement(x))?.ToList() ?? []; var filter = Builders.Filter.Eq(x => x.Id, agentId); var update = Builders.Update - .Set(x => x.Mcps, elements) + .Set(x => x.McpTools, elements) .Set(x => x.UpdatedTime, DateTime.UtcNow); _dc.Agents.UpdateOne(filter, update); @@ -346,7 +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.Acps.Select(u => AgentCPMongoElement.ToMongoElement(u)).ToList()) + .Set(x => x.McpTools, agent.McpTools.Select(u => AgentMCPToolMongoElement.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)) @@ -527,7 +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.Acps?.Select(u => AgentCPMongoElement.ToMongoElement(u))?.ToList() ?? [], + McpTools = x.McpTools?.Select(u => AgentMCPToolMongoElement.ToMongoElement(u))?.ToList() ?? [], KnowledgeBases = x.KnowledgeBases?.Select(k => AgentKnowledgeBaseMongoElement.ToMongoElement(k))?.ToList() ?? [], Rules = x.Rules?.Select(e => AgentRuleMongoElement.ToMongoElement(e))?.ToList() ?? [], CreatedTime = x.CreatedDateTime, @@ -622,7 +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() ?? [], - Acps = agentDoc.Mcps?.Select(u => AgentCPMongoElement.ToDomainElement(u))?.ToList() ?? [], + McpTools = agentDoc.McpTools?.Select(u => AgentMCPToolMongoElement.ToDomainElement(u))?.ToList() ?? [], KnowledgeBases = agentDoc.KnowledgeBases?.Select(x => AgentKnowledgeBaseMongoElement.ToDomainElement(x))?.ToList() ?? [], Rules = agentDoc.Rules?.Select(e => AgentRuleMongoElement.ToDomainElement(e))?.ToList() ?? [] };