Skip to content

Commit 927184e

Browse files
committed
Refactor InvokeFunction code
Refactor the InvokeFunction code by categorizing the dummy function, function callback, and MCP tool invocation logic into three distinct classes
1 parent a3aabe2 commit 927184e

20 files changed

+243
-251
lines changed

BotSharp.sln

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.Realtime", "s
131131
EndProject
132132
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.PizzaBot.MCPServer", "tests\BotSharp.PizzaBot.MCPServer\BotSharp.PizzaBot.MCPServer.csproj", "{8D2AD45F-836A-516F-DE6A-71443CEBB18A}"
133133
EndProject
134-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.MCP", "src\Infrastructure\BotSharp.Core.MCP\BotSharp.Core.MCP.csproj", "{534D1DD5-9D62-115C-F230-47080D76CE52}"
135-
EndProject
136134
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Test.ComputerUse", "tests\BotSharp.Test.ComputerUse\BotSharp.Test.ComputerUse.csproj", "{C19D9AC1-97DD-8E65-E8DB-D295A095AA2D}"
137135
EndProject
138136
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.OsDriver", "src\Plugins\BotSharp.Plugin.OsDriver\BotSharp.Plugin.OsDriver.csproj", "{B268E2F0-060F-8466-7D81-ABA4D735CA59}"
@@ -553,14 +551,6 @@ Global
553551
{8D2AD45F-836A-516F-DE6A-71443CEBB18A}.Release|Any CPU.Build.0 = Release|Any CPU
554552
{8D2AD45F-836A-516F-DE6A-71443CEBB18A}.Release|x64.ActiveCfg = Release|Any CPU
555553
{8D2AD45F-836A-516F-DE6A-71443CEBB18A}.Release|x64.Build.0 = Release|Any CPU
556-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
557-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|Any CPU.Build.0 = Debug|Any CPU
558-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|x64.ActiveCfg = Debug|Any CPU
559-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|x64.Build.0 = Debug|Any CPU
560-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|Any CPU.ActiveCfg = Release|Any CPU
561-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|Any CPU.Build.0 = Release|Any CPU
562-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|x64.ActiveCfg = Release|Any CPU
563-
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|x64.Build.0 = Release|Any CPU
564554
{C19D9AC1-97DD-8E65-E8DB-D295A095AA2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
565555
{C19D9AC1-97DD-8E65-E8DB-D295A095AA2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
566556
{C19D9AC1-97DD-8E65-E8DB-D295A095AA2D}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -672,7 +662,6 @@ Global
672662
{AF329442-B48E-4B48-A18A-1C869D1BA6F5} = {D5293208-2BEF-42FC-A64C-5954F61720BA}
673663
{781F1465-365C-0F22-1775-25025DAFA4C7} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
674664
{8D2AD45F-836A-516F-DE6A-71443CEBB18A} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
675-
{534D1DD5-9D62-115C-F230-47080D76CE52} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
676665
{C19D9AC1-97DD-8E65-E8DB-D295A095AA2D} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
677666
{B268E2F0-060F-8466-7D81-ABA4D735CA59} = {51AFE054-AE99-497D-A593-69BAEFB5106F}
678667
{970BE341-9AC8-99A5-6572-E703C1E02FCB} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}

IFunctionExecutor.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace BotSharp.Core.Routing
8+
{
9+
public interface IFunctionExecutor
10+
{
11+
public Task<bool> Execute(RoleDialogModel message);
12+
13+
public Task<string> GetIndication(RoleDialogModel message);
14+
}
15+
}

src/Infrastructure/BotSharp.Core.MCP/BotSharp.Core.MCP.csproj

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/Infrastructure/BotSharp.Core.MCP/BotSharpMCPExtensions.cs

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/Infrastructure/BotSharp.Core.MCP/Using.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
<PackageReference Include="Microsoft.Extensions.Http" />
222222
<PackageReference Include="Nanoid" />
223223
<PackageReference Include="Rougamo.Fody" />
224+
<PackageReference Include="ModelContextProtocol" />
224225
</ItemGroup>
225226

226227
<ItemGroup>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using BotSharp.Core.MCP.Hooks;
2+
using BotSharp.Core.MCP.Managers;
3+
using BotSharp.Core.MCP.Services;
4+
using BotSharp.Core.MCP.Settings;
5+
using Microsoft.Extensions.Configuration;
6+
7+
namespace BotSharp.Core.MCP;
8+
9+
public static class BotSharpMcpExtensions
10+
{
11+
/// <summary>
12+
/// Add mcp
13+
/// </summary>
14+
/// <param name="services"></param>
15+
/// <param name="config"></param>
16+
/// <returns></returns>
17+
public static IServiceCollection AddBotSharpMCP(this IServiceCollection services, IConfiguration config)
18+
{
19+
var settings = config.GetSection("MCP").Get<McpSettings>();
20+
services.AddScoped(provider => settings);
21+
22+
if (settings != null && settings.Enabled && !settings.McpServerConfigs.IsNullOrEmpty())
23+
{
24+
services.AddScoped<IMcpService, McpService>();
25+
26+
var clientManager = new McpClientManager(settings);
27+
services.AddScoped(provider => clientManager);
28+
29+
// Register hooks
30+
services.AddScoped<IAgentHook, McpToolAgentHook>();
31+
}
32+
return services;
33+
}
34+
35+
}

src/Infrastructure/BotSharp.Core.MCP/Services/McpService.cs renamed to src/Infrastructure/BotSharp.Core/MCP/Services/McpService.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1+
using BotSharp.Core.MCP.Managers;
12
using BotSharp.Core.MCP.Settings;
23
using Microsoft.Extensions.Logging;
4+
using ModelContextProtocol.Client;
35

46
namespace BotSharp.Core.MCP.Services;
57

68
public class McpService : IMcpService
79
{
810
private readonly IServiceProvider _services;
911
private readonly ILogger<McpService> _logger;
12+
private readonly McpClientManager _mcpClientManager;
1013

1114
public McpService(
1215
IServiceProvider services,
13-
ILogger<McpService> logger)
16+
ILogger<McpService> logger,
17+
McpClientManager mcpClient)
1418
{
1519
_services = services;
1620
_logger = logger;
21+
_mcpClientManager = mcpClient;
1722
}
1823

1924
public IEnumerable<McpServerOptionModel> GetServerConfigs()
@@ -24,9 +29,9 @@ public IEnumerable<McpServerOptionModel> GetServerConfigs()
2429

2530
foreach (var config in configs)
2631
{
27-
var tools = _services.GetServices<IFunctionCallback>()
28-
.Where(x => x.Provider == config.Name)
29-
.Select(x => x.Name);
32+
var tools = _mcpClientManager.GetMcpClientAsync(config.Id)
33+
.Result.ListToolsAsync()
34+
.Result.Select(x=> x.Name);
3035

3136
options.Add(new McpServerOptionModel
3237
{
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using BotSharp.Abstraction.Templating;
2+
3+
namespace BotSharp.Core.Routing.Executor;
4+
5+
public class DummyFunctionExecutor: IFunctionExecutor
6+
{
7+
private FunctionDef functionDef;
8+
private readonly IServiceProvider _services;
9+
10+
public DummyFunctionExecutor(FunctionDef function, IServiceProvider services)
11+
{
12+
functionDef = function;
13+
_services = services;
14+
}
15+
16+
17+
public async Task<bool> ExecuteAsync(RoleDialogModel message)
18+
{
19+
var render = _services.GetRequiredService<ITemplateRender>();
20+
var state = _services.GetRequiredService<IConversationStateService>();
21+
22+
var dict = new Dictionary<string, object>();
23+
foreach (var item in state.GetStates())
24+
{
25+
dict[item.Key] = item.Value;
26+
}
27+
28+
var text = render.Render(functionDef.Output, dict);
29+
message.Content = text;
30+
return true;
31+
}
32+
33+
public async Task<string> GetIndicatorAsync(RoleDialogModel message)
34+
{
35+
return "Running";
36+
}
37+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using BotSharp.Abstraction.Functions;
2+
3+
namespace BotSharp.Core.Routing.Executor;
4+
5+
public class FunctionCallbackExecutor : IFunctionExecutor
6+
{
7+
IFunctionCallback functionCallback;
8+
9+
public FunctionCallbackExecutor(IFunctionCallback functionCallback)
10+
{
11+
this.functionCallback = functionCallback;
12+
}
13+
14+
public async Task<bool> ExecuteAsync(RoleDialogModel message)
15+
{
16+
return await functionCallback.Execute(message);
17+
}
18+
19+
public async Task<string> GetIndicatorAsync(RoleDialogModel message)
20+
{
21+
return await functionCallback.GetIndication(message);
22+
}
23+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using BotSharp.Abstraction.Functions;
2+
3+
namespace BotSharp.Core.Routing.Executor;
4+
5+
internal class FunctionExecutorFactory
6+
{
7+
public static IFunctionExecutor Create(string functionName, Agent agent, IFunctionCallback functioncall, IServiceProvider serviceProvider)
8+
{
9+
if(functioncall != null)
10+
{
11+
return new FunctionCallbackExecutor(functioncall);
12+
}
13+
14+
var funDef = agent?.Functions?.FirstOrDefault(x => x.Name == functionName);
15+
if (funDef != null)
16+
{
17+
if (!string.IsNullOrWhiteSpace(funDef?.Output))
18+
{
19+
return new DummyFunctionExecutor(funDef,serviceProvider);
20+
}
21+
}
22+
else
23+
{
24+
funDef = agent?.SecondaryFunctions?.FirstOrDefault(x => x.Name == functionName);
25+
if (funDef != null)
26+
{
27+
if (!string.IsNullOrWhiteSpace(funDef?.Output))
28+
{
29+
return new DummyFunctionExecutor(funDef, serviceProvider);
30+
}
31+
else
32+
{
33+
var mcpServerId = agent?.McpTools?.Where(x => x.Functions.Any(y => y.Name == funDef.Name))
34+
.FirstOrDefault().ServerId;
35+
return new MCPFunctionExecutor(mcpServerId, functionName, serviceProvider);
36+
}
37+
}
38+
}
39+
return null;
40+
}
41+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace BotSharp.Core.Routing.Executor;
2+
3+
public interface IFunctionExecutor
4+
{
5+
public Task<bool> ExecuteAsync(RoleDialogModel message);
6+
7+
public Task<string> GetIndicatorAsync(RoleDialogModel message);
8+
}

0 commit comments

Comments
 (0)