diff --git a/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj b/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj index 9162cd16..121afd35 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj +++ b/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj @@ -47,7 +47,8 @@ - + + diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index 00c82ebe..6e49658d 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -1,4 +1,7 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Core.Mcp; +using ModelContextProtocol.Client; +using ModelContextProtocol.Protocol.Types; namespace BotSharp.OpenAPI.Controllers; @@ -9,15 +12,19 @@ public class AgentController : ControllerBase private readonly IAgentService _agentService; private readonly IUserIdentity _user; private readonly IServiceProvider _services; + private readonly MCPClientManager _clientManager; public AgentController( IAgentService agentService, IUserIdentity user, - IServiceProvider services) + IServiceProvider services, + MCPClientManager mCPClientManager + ) { _agentService = agentService; _user = user; _services = services; + _clientManager = mCPClientManager; } [HttpGet("/agent/settings")] @@ -167,6 +174,16 @@ public class AgentController : ControllerBase return utilities.Where(x => !string.IsNullOrWhiteSpace(x.Name)).OrderBy(x => x.Name).ToList(); } + [HttpGet("/agent/mcp/tools")] + public async Task> GetMCPTools(string serverId) + { + var client = await _clientManager.GetMcpClientAsync(serverId); + var tools = await client.ListToolsAsync().ToListAsync(); + + return tools.Where(x => !string.IsNullOrWhiteSpace(x.Name)) + .OrderBy(x => x.Name).ToList(); + } + [HttpGet("/agent/labels")] public async Task> GetAgentLabels() { diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index cbd9ded0..7da8de59 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -79,7 +79,6 @@ - @@ -122,6 +121,7 @@ + diff --git a/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs b/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs index 9433c6a8..4fa39c7c 100644 --- a/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs +++ b/tests/BotSharp.Plugin.PizzaBot/Functions/GetPizzaPricesFn.cs @@ -1,21 +1,21 @@ -//using BotSharp.Abstraction.Conversations.Models; -//using System.Text.Json; +using BotSharp.Abstraction.Conversations.Models; +using System.Text.Json; -//namespace BotSharp.Plugin.PizzaBot.Functions; +namespace BotSharp.Plugin.PizzaBot.Functions; -//public class GetPizzaPricesFn : IFunctionCallback -//{ -// public string Name => "get_pizza_price"; +public class GetPizzaPricesFn : IFunctionCallback +{ + public string Name => "get_pizza_price"; -// public async Task Execute(RoleDialogModel message) -// { -// message.Data = new -// { -// pepperoni_unit_price = 3.2, -// cheese_unit_price = 3.5, -// margherita_unit_price = 3.8, -// }; -// message.Content = JsonSerializer.Serialize(message.Data); -// return true; -// } -//} + public async Task Execute(RoleDialogModel message) + { + message.Data = new + { + pepperoni_unit_price = 3.2, + cheese_unit_price = 3.5, + margherita_unit_price = 3.8, + }; + message.Content = JsonSerializer.Serialize(message.Data); + return true; + } +} diff --git a/tests/BotSharp.Plugin.PizzaBot/Functions/MakePaymentFn.cs b/tests/BotSharp.Plugin.PizzaBot/Functions/MakePaymentFn.cs index 5a34a6ce..144eb05a 100644 --- a/tests/BotSharp.Plugin.PizzaBot/Functions/MakePaymentFn.cs +++ b/tests/BotSharp.Plugin.PizzaBot/Functions/MakePaymentFn.cs @@ -1,19 +1,19 @@ -//using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Conversations.Models; -//namespace BotSharp.Plugin.PizzaBot.Functions; +namespace BotSharp.Plugin.PizzaBot.Functions; -//public class MakePaymentFn : IFunctionCallback -//{ -// public string Name => "make_payment"; +public class MakePaymentFn : IFunctionCallback +{ + public string Name => "make_payment"; -// public async Task Execute(RoleDialogModel message) -// { -// message.Content = "Payment proceed successfully. Thank you for your business. Have a great day!"; -// message.Data = new -// { -// Transaction = Guid.NewGuid().ToString(), -// Status = "Success" -// }; -// return true; -// } -//} + public async Task Execute(RoleDialogModel message) + { + message.Content = "Payment proceed successfully. Thank you for your business. Have a great day!"; + message.Data = new + { + Transaction = Guid.NewGuid().ToString(), + Status = "Success" + }; + return true; + } +} diff --git a/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs b/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs index 47d27363..87466956 100644 --- a/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs +++ b/tests/BotSharp.Plugin.PizzaBot/Functions/PlaceOrderFn.cs @@ -1,24 +1,24 @@ -//using BotSharp.Abstraction.Conversations; -//using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Conversations.Models; -//namespace BotSharp.Plugin.PizzaBot.Functions; +namespace BotSharp.Plugin.PizzaBot.Functions; -//public class PlaceOrderFn : IFunctionCallback -//{ -// public string Name => "place_an_order"; +public class PlaceOrderFn : IFunctionCallback +{ + public string Name => "place_an_order"; -// private readonly IServiceProvider _service; -// public PlaceOrderFn(IServiceProvider service) -// { -// _service = service; -// } + private readonly IServiceProvider _service; + public PlaceOrderFn(IServiceProvider service) + { + _service = service; + } -// public async Task Execute(RoleDialogModel message) -// { -// message.Content = "The order number is P123-01"; -// var state = _service.GetRequiredService(); -// state.SetState("order_number", "P123-01"); + public async Task Execute(RoleDialogModel message) + { + message.Content = "The order number is P123-01"; + var state = _service.GetRequiredService(); + state.SetState("order_number", "P123-01"); -// return true; -// } -//} + return true; + } +} diff --git a/tests/BotSharp.Plugin.PizzaBot/Hooks/PizzaBotConversationHook.cs b/tests/BotSharp.Plugin.PizzaBot/Hooks/PizzaBotConversationHook.cs index 92083ee7..3ebd4df3 100644 --- a/tests/BotSharp.Plugin.PizzaBot/Hooks/PizzaBotConversationHook.cs +++ b/tests/BotSharp.Plugin.PizzaBot/Hooks/PizzaBotConversationHook.cs @@ -32,16 +32,20 @@ public class PizzaBotConversationHook : ConversationHookBase return base.OnTaskCompleted(message); } + #if USE_BOTSHARP public override async Task OnResponseGenerated(RoleDialogModel message) { var agentService = _services.GetRequiredService(); var state = _services.GetRequiredService(); var agent = await agentService.LoadAgent(message.CurrentAgentId); + if (agent.McpTools.Any(item => item.Functions.Any(x => x.Name == message.FunctionName))) { var data = JsonDocument.Parse(JsonSerializer.Serialize(message.Data)); state.SaveStateByArgs(data); } + await base.OnResponseGenerated(message); } + #endif } diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/get_pizza_price.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/get_pizza_price.json index 1ecdbb65..e2eaac31 100644 --- a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/get_pizza_price.json +++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/get_pizza_price.json @@ -1,18 +1,18 @@ -//{ -// "name": "get_pizza_price", -// "description": "call this function to get the pizza price", -// "parameters": { -// "type": "object", -// "properties": { -// "pizza_type": { -// "type": "string", -// "description": "The pizza type." -// }, -// "quantity": { -// "type": "string", -// "description": "quantity of pizza." -// } -// }, -// "required": [ "pizza_type", "quantity" ] -// } -//} \ No newline at end of file +{ + "name": "get_pizza_price", + "description": "call this function to get the pizza price", + "parameters": { + "type": "object", + "properties": { + "pizza_type": { + "type": "string", + "description": "The pizza type." + }, + "quantity": { + "type": "string", + "description": "quantity of pizza." + } + }, + "required": [ "pizza_type", "quantity" ] + } +} \ No newline at end of file diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json index a01f0005..d5514fba 100644 --- a/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json +++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/c2b57a74-ae4e-4c81-b3ad-9ac5bff982bd/functions/place_an_order.json @@ -1,22 +1,22 @@ -//{ -// "name": "place_an_order", -// "description": "Place an order when user has confirmed the pizza type and quantity.", -// "parameters": { -// "type": "object", -// "properties": { -// "pizza_type": { -// "type": "string", -// "description": "The pizza type." -// }, -// "quantity": { -// "type": "number", -// "description": "quantity of pizza." -// }, -// "unit_price": { -// "type": "number", -// "description": "unit price" -// } -// }, -// "required": [ "pizza_type", "quantity", "unit_price" ] -// } -//} \ No newline at end of file +{ + "name": "place_an_order", + "description": "Place an order when user has confirmed the pizza type and quantity.", + "parameters": { + "type": "object", + "properties": { + "pizza_type": { + "type": "string", + "description": "The pizza type." + }, + "quantity": { + "type": "number", + "description": "quantity of pizza." + }, + "unit_price": { + "type": "number", + "description": "unit price" + } + }, + "required": [ "pizza_type", "quantity", "unit_price" ] + } +} \ No newline at end of file diff --git a/tests/BotSharp.Plugin.PizzaBot/data/agents/fe8c60aa-b114-4ef3-93cb-a8efeac80f75/functions/make_payment.json b/tests/BotSharp.Plugin.PizzaBot/data/agents/fe8c60aa-b114-4ef3-93cb-a8efeac80f75/functions/make_payment.json index 914f215e..82782c94 100644 --- a/tests/BotSharp.Plugin.PizzaBot/data/agents/fe8c60aa-b114-4ef3-93cb-a8efeac80f75/functions/make_payment.json +++ b/tests/BotSharp.Plugin.PizzaBot/data/agents/fe8c60aa-b114-4ef3-93cb-a8efeac80f75/functions/make_payment.json @@ -1,18 +1,18 @@ -//{ -// "name": "make_payment", -// "description": "call this function to make payment", -// "parameters": { -// "type": "object", -// "properties": { -// "order_number": { -// "type": "string", -// "description": "order number." -// }, -// "total_amount": { -// "type": "string", -// "description": "total amount." -// } -// }, -// "required": [ "order_number", "total_amount" ] -// } -//} \ No newline at end of file +{ + "name": "make_payment", + "description": "call this function to make payment", + "parameters": { + "type": "object", + "properties": { + "order_number": { + "type": "string", + "description": "order number." + }, + "total_amount": { + "type": "string", + "description": "total amount." + } + }, + "required": [ "order_number", "total_amount" ] + } +} \ No newline at end of file