Merge branch 'SciSharp:master' into master
This commit is contained in:
commit
994d6df06a
22
BotSharp.sln
22
BotSharp.sln
|
|
@ -127,12 +127,12 @@ 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", "{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.Realtime", "src\Infrastructure\BotSharp.Core.Realtime\BotSharp.Core.Realtime.csproj", "{781F1465-365C-0F22-1775-25025DAFA4C7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.PizzaBot.MCPServer", "tests\BotSharp.PizzaBot.MCPServer\BotSharp.PizzaBot.MCPServer.csproj", "{8D2AD45F-836A-516F-DE6A-71443CEBB18A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Core.MCP", "src\Infrastructure\BotSharp.Core.MCP\BotSharp.Core.MCP.csproj", "{534D1DD5-9D62-115C-F230-47080D76CE52}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -525,14 +525,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
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{781F1465-365C-0F22-1775-25025DAFA4C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{781F1465-365C-0F22-1775-25025DAFA4C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{781F1465-365C-0F22-1775-25025DAFA4C7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -549,6 +541,14 @@ Global
|
|||
{8D2AD45F-836A-516F-DE6A-71443CEBB18A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D2AD45F-836A-516F-DE6A-71443CEBB18A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8D2AD45F-836A-516F-DE6A-71443CEBB18A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -610,9 +610,9 @@ 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}
|
||||
{684781D5-3DD4-6A0B-B53F-0A362CD6BB0C} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
|
||||
{781F1465-365C-0F22-1775-25025DAFA4C7} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
|
||||
{8D2AD45F-836A-516F-DE6A-71443CEBB18A} = {32FAFFFE-A4CB-4FEE-BF7C-84518BBC6DCC}
|
||||
{534D1DD5-9D62-115C-F230-47080D76CE52} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
It's written in C# running on .Net Core that is full cross-platform framework, the plug-in and pipeline flow execution design is adopted to completely decouple the plug-ins. C# is a enterprise grade programming language which is widely used to code business logic in information management related system. More friendly to corporate developers. BotSharp adopts machine learning algorithm in C# directly. That will facilitate the feature of the typed language C#, and be more easier when refactoring code in system scope.
|
||||
|
||||
**BotSharp** is in accordance with components principle strictly, decouples every part that is needed in the platform builder. So you can choose different UI/UX, or pick up a different LLM providers. They are all modulized based on unified interfaces. **BotSharp** provides an advanced Agent abstraction layer to efficiently manage complex application scenarios in enterprises, allowing enterprise developers to efficiently integrate AI into business systems.
|
||||
**BotSharp** is in accordance with components principle strictly, decouples every part that is needed in the platform builder. So you can choose different UI/UX, or pick up a different LLM providers. They are all modularized based on unified interfaces. **BotSharp** provides an advanced Agent abstraction layer to efficiently manage complex application scenarios in enterprises, allowing enterprise developers to efficiently integrate AI into business systems.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public abstract class AgentHookBase : IAgentHook
|
|||
|
||||
}
|
||||
|
||||
public virtual void OnAgentMCPToolLoaded(Agent agent)
|
||||
public virtual void OnAgentMcpToolLoaded(Agent agent)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public interface IAgentHook
|
|||
|
||||
void OnAgentUtilityLoaded(Agent agent);
|
||||
|
||||
void OnAgentMCPToolLoaded(Agent agent);
|
||||
void OnAgentMcpToolLoaded(Agent agent);
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when agent is loaded completely.
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ public class Agent
|
|||
/// <summary>
|
||||
/// Agent MCP Tools
|
||||
/// </summary>
|
||||
public List<MCPTool> McpTools { get; set; } = new();
|
||||
public List<McpTool> McpTools { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Agent rules
|
||||
|
|
@ -305,7 +305,7 @@ public class Agent
|
|||
return this;
|
||||
}
|
||||
|
||||
public Agent SetMcps(List<MCPTool> mcps)
|
||||
public Agent SetMcpTools(List<McpTool>? mcps)
|
||||
{
|
||||
McpTools = mcps ?? [];
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,26 @@
|
|||
namespace BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
public class MCPTool
|
||||
public class McpTool
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string ServerId { get; set; }
|
||||
|
||||
public bool Disabled { get; set; }
|
||||
public IEnumerable<McpFunction> Functions { get; set; } = [];
|
||||
|
||||
public IEnumerable<MCPFunction> Functions { get; set; } = [];
|
||||
|
||||
public MCPTool()
|
||||
public McpTool()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public MCPTool(
|
||||
IEnumerable<MCPFunction>? functions = null)
|
||||
public McpTool(
|
||||
string name,
|
||||
string serverId,
|
||||
bool disabled = false,
|
||||
IEnumerable<McpFunction>? functions = null)
|
||||
{
|
||||
Name = name;
|
||||
ServerId = serverId;
|
||||
Disabled = disabled;
|
||||
Functions = functions ?? [];
|
||||
}
|
||||
|
||||
|
|
@ -26,12 +31,12 @@ public class MCPTool
|
|||
}
|
||||
|
||||
|
||||
public class MCPFunction
|
||||
public class McpFunction
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public MCPFunction(string name)
|
||||
public McpFunction(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
using BotSharp.Abstraction.Instructs.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Files;
|
||||
|
||||
public interface IFileInstructService
|
||||
{
|
||||
#region Image
|
||||
Task<string> ReadImages(string? provider, string? model, string text, IEnumerable<InstructFileModel> images, string? agentId = null);
|
||||
Task<RoleDialogModel> GenerateImage(string? provider, string? model, string text, string? agentId = null);
|
||||
Task<RoleDialogModel> VaryImage(string? provider, string? model, InstructFileModel image, string? agentId = null);
|
||||
Task<RoleDialogModel> EditImage(string? provider, string? model, string text, InstructFileModel image, string? agentId = null);
|
||||
Task<RoleDialogModel> EditImage(string? provider, string? model, string text, InstructFileModel image, InstructFileModel mask, string? agentId = null);
|
||||
Task<string> ReadImages(string text, IEnumerable<InstructFileModel> images, InstructOptions? options = null);
|
||||
Task<RoleDialogModel> GenerateImage(string text, InstructOptions? options = null);
|
||||
Task<RoleDialogModel> VaryImage(InstructFileModel image, InstructOptions? options = null);
|
||||
Task<RoleDialogModel> EditImage(string text, InstructFileModel image, InstructOptions? options = null);
|
||||
Task<RoleDialogModel> EditImage(string text, InstructFileModel image, InstructFileModel mask, InstructOptions? options = null);
|
||||
#endregion
|
||||
|
||||
#region Pdf
|
||||
|
|
@ -17,11 +19,11 @@ public interface IFileInstructService
|
|||
/// <param name="prompt"></param>
|
||||
/// <param name="files">Pdf files</param>
|
||||
/// <returns></returns>
|
||||
Task<string> ReadPdf(string? provider, string? model, string? modelId, string prompt, List<InstructFileModel> files, string? agentId = null);
|
||||
Task<string> ReadPdf(string text, List<InstructFileModel> files, InstructOptions? options = null);
|
||||
#endregion
|
||||
|
||||
#region Audio
|
||||
Task<string> SpeechToText(string? provider, string? model, InstructFileModel audio, string? text = null);
|
||||
Task<string> SpeechToText(InstructFileModel audio, string? text = null, InstructOptions? options = null);
|
||||
#endregion
|
||||
|
||||
#region Select file
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ public interface IInstructService
|
|||
/// <param name="templateName">Template name</param>
|
||||
/// <param name="instruction">System prompt</param>
|
||||
/// <returns></returns>
|
||||
Task<InstructResult> Execute(string agentId, RoleDialogModel message, string? templateName = null, string? instruction = null);
|
||||
Task<InstructResult> Execute(string agentId, RoleDialogModel message,
|
||||
string? templateName = null, string? instruction = null, IEnumerable<InstructFileModel>? files = null);
|
||||
|
||||
/// <summary>
|
||||
/// A generic way to execute completion by using specified instruction or template
|
||||
|
|
@ -22,5 +23,5 @@ public interface IInstructService
|
|||
/// <param name="agentId">Agent id</param>
|
||||
/// <param name="options">Llm Provider, model, message, prompt data</param>
|
||||
/// <returns></returns>
|
||||
Task<T?> Instruct<T>(string instruction, string agentId, InstructOptions options) where T : class;
|
||||
Task<T?> Instruct<T>(string text, InstructOptions? options = null) where T : class;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,23 +5,28 @@ public class InstructOptions
|
|||
/// <summary>
|
||||
/// Llm provider
|
||||
/// </summary>
|
||||
public string Provider { get; set; } = null!;
|
||||
public string? Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Llm model
|
||||
/// </summary>
|
||||
public string Model { get; set; } = null!;
|
||||
public string? Model { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Agent
|
||||
/// </summary>
|
||||
public string? AgentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Agent template name
|
||||
/// </summary>
|
||||
public string? TemplateName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Conversation id. When this field is not null, it will get dialogs from conversation.
|
||||
/// </summary>
|
||||
public string? ConversationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The single message. It can be append to the whole dialogs or sent alone.
|
||||
/// </summary>
|
||||
public string? Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data to fill in prompt
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@ namespace BotSharp.Abstraction.Plugins;
|
|||
public class PluginSettings
|
||||
{
|
||||
public string[] Assemblies { get; set; } = new string[0];
|
||||
|
||||
public string[] ExcludedFunctions { get; set; } = new string[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,14 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Core.Mcp.Functions;
|
||||
using BotSharp.Core.Mcp.Settings;
|
||||
using BotSharp.Core.Mcp;
|
||||
using BotSharp.MCP.Hooks;
|
||||
using BotSharp.Core.MCP.Functions;
|
||||
using BotSharp.Core.MCP.Settings;
|
||||
using BotSharp.Core.MCP.Hooks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using ModelContextProtocol.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ModelContextProtocol.Client;
|
||||
using BotSharp.Core.MCP.Managers;
|
||||
|
||||
namespace BotSharp.MCP;
|
||||
namespace BotSharp.Core.MCP;
|
||||
|
||||
public static class BotSharpMCPExtensions
|
||||
public static class BotSharpMcpExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Add mcp
|
||||
|
|
@ -25,15 +16,13 @@ public static class BotSharpMCPExtensions
|
|||
/// <param name="services"></param>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddBotSharpMCP(this IServiceCollection services,
|
||||
IConfiguration config)
|
||||
public static IServiceCollection AddBotSharpMCP(this IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
var settings = config.GetSection("MCPSettings").Get<MCPSettings>();
|
||||
services.AddScoped<MCPSettings>(provider => { return settings; });
|
||||
if (settings != null)
|
||||
var settings = config.GetSection("MCPSettings").Get<McpSettings>();
|
||||
services.AddScoped<McpSettings>(provider => { return settings; });
|
||||
if (settings != null && !settings.McpServerConfigs.IsNullOrEmpty())
|
||||
{
|
||||
|
||||
var clientManager = new MCPClientManager(settings);
|
||||
var clientManager = new McpClientManager(settings);
|
||||
services.AddSingleton(clientManager);
|
||||
|
||||
foreach (var server in settings.McpServerConfigs)
|
||||
|
|
@ -43,13 +32,14 @@ public static class BotSharpMCPExtensions
|
|||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
// Register hooks
|
||||
services.AddScoped<IAgentHook, MCPToolAgentHook>();
|
||||
services.AddScoped<IAgentHook, McpToolAgentHook>();
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
private static async Task RegisterFunctionCall(IServiceCollection services, McpServerConfig server, MCPClientManager clientManager)
|
||||
private static async Task RegisterFunctionCall(IServiceCollection services, McpServerConfig server, McpClientManager clientManager)
|
||||
{
|
||||
var client = await clientManager.GetMcpClientAsync(server.Id);
|
||||
var tools = await client.ListToolsAsync();
|
||||
|
|
@ -1,27 +1,18 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Abstraction.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using BotSharp.Core.MCP.Managers;
|
||||
using ModelContextProtocol.Client;
|
||||
|
||||
namespace BotSharp.Core.Mcp.Functions;
|
||||
namespace BotSharp.Core.MCP.Functions;
|
||||
|
||||
public class McpToolAdapter : IFunctionCallback
|
||||
{
|
||||
private readonly McpClientTool _tool;
|
||||
private readonly MCPClientManager _clientManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly McpClientManager _clientManager;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public McpToolAdapter(IServiceProvider provider, McpClientTool tool, MCPClientManager client)
|
||||
public McpToolAdapter(IServiceProvider services, McpClientTool tool, McpClientManager client)
|
||||
{
|
||||
_serviceProvider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
_services = services ?? throw new ArgumentNullException(nameof(services));
|
||||
_tool = tool ?? throw new ArgumentNullException(nameof(tool));
|
||||
_clientManager = client ?? throw new ArgumentNullException(nameof(client));
|
||||
}
|
||||
|
|
@ -33,21 +24,18 @@ public class McpToolAdapter : IFunctionCallback
|
|||
// Convert arguments to dictionary format expected by mcpdotnet
|
||||
Dictionary<string, object> argDict = JsonToDictionary(message.FunctionArgs);
|
||||
var currentAgentId = message.CurrentAgentId;
|
||||
var agentService = _serviceProvider.GetRequiredService<IAgentService>();
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agent = await agentService.LoadAgent(currentAgentId);
|
||||
var serverId = agent.McpTools.Where(t => t.Functions.Any(f => f.Name == Name)).FirstOrDefault().ServerId;
|
||||
|
||||
var client = await _clientManager.GetMcpClientAsync(serverId);
|
||||
|
||||
// Call the tool through mcpdotnet
|
||||
var result = await client.CallToolAsync(
|
||||
_tool.Name,
|
||||
argDict.Count == 0 ? new() : argDict
|
||||
);
|
||||
var result = await client.CallToolAsync(_tool.Name, argDict.IsNullOrEmpty() ? new() : argDict);
|
||||
|
||||
// Extract the text content from the result
|
||||
var json = string.Join("\n", result.Content
|
||||
.Where(c => c.Type == "text")
|
||||
.Select(c => c.Text));
|
||||
var json = string.Join("\n", result.Content.Where(c => c.Type == "text").Select(c => c.Text));
|
||||
|
||||
message.Content = json;
|
||||
message.Data = json.JsonContent();
|
||||
return true;
|
||||
|
|
@ -1,13 +1,9 @@
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using ModelContextProtocol.Client;
|
||||
|
||||
namespace BotSharp.Core.MCP;
|
||||
namespace BotSharp.Core.MCP.Helpers;
|
||||
|
||||
internal static class AIFunctionUtilities
|
||||
internal static class AiFunctionHelper
|
||||
{
|
||||
public static FunctionDef MapToFunctionDef(McpClientTool tool)
|
||||
{
|
||||
|
|
@ -19,7 +15,7 @@ internal static class AIFunctionUtilities
|
|||
var properties = tool.JsonSchema.GetProperty("properties");
|
||||
var required = tool.JsonSchema.GetProperty("required");
|
||||
|
||||
FunctionDef funDef = new FunctionDef
|
||||
var funDef = new FunctionDef
|
||||
{
|
||||
Name = tool.Name,
|
||||
Description = tool.Description ?? string.Empty,
|
||||
|
|
@ -1,41 +1,32 @@
|
|||
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 BotSharp.Core.MCP.Helpers;
|
||||
using BotSharp.Core.MCP.Managers;
|
||||
using ModelContextProtocol.Client;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BotSharp.MCP.Hooks;
|
||||
namespace BotSharp.Core.MCP.Hooks;
|
||||
|
||||
public class MCPToolAgentHook : AgentHookBase
|
||||
public class McpToolAgentHook : AgentHookBase
|
||||
{
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public MCPToolAgentHook(IServiceProvider services, AgentSettings settings)
|
||||
public McpToolAgentHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentMCPToolLoaded(Agent agent)
|
||||
public override void OnAgentMcpToolLoaded(Agent agent)
|
||||
{
|
||||
if (agent.Type == AgentType.Routing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
if (!isConvMode) return;
|
||||
|
||||
agent.SecondaryFunctions ??= [];
|
||||
|
||||
var functions = GetMCPContent(agent).Result;
|
||||
|
||||
var functions = GetMcpContent(agent).Result;
|
||||
foreach (var fn in functions)
|
||||
{
|
||||
if (!agent.SecondaryFunctions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
|
|
@ -45,11 +36,11 @@ public class MCPToolAgentHook : AgentHookBase
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<FunctionDef>> GetMCPContent(Agent agent)
|
||||
private async Task<IEnumerable<FunctionDef>> GetMcpContent(Agent agent)
|
||||
{
|
||||
List<FunctionDef> functionDefs = new List<FunctionDef>();
|
||||
var mcpClientManager = _services.GetRequiredService<MCPClientManager>();
|
||||
var mcps = agent.McpTools;
|
||||
var functionDefs = new List<FunctionDef>();
|
||||
var mcpClientManager = _services.GetRequiredService<McpClientManager>();
|
||||
var mcps = agent.McpTools.Where(x => !x.Disabled);
|
||||
foreach (var item in mcps)
|
||||
{
|
||||
var mcpClient = await mcpClientManager.GetMcpClientAsync(item.ServerId);
|
||||
|
|
@ -57,9 +48,9 @@ public class MCPToolAgentHook : AgentHookBase
|
|||
{
|
||||
var tools = await mcpClient.ListToolsAsync();
|
||||
var toolnames = item.Functions.Select(x => x.Name).ToList();
|
||||
foreach (var tool in tools.ToList().Where(x => toolnames.Contains(x.Name, StringComparer.OrdinalIgnoreCase)))
|
||||
foreach (var tool in tools.Where(x => toolnames.Contains(x.Name, StringComparer.OrdinalIgnoreCase)))
|
||||
{
|
||||
var funDef = AIFunctionUtilities.MapToFunctionDef(tool);
|
||||
var funDef = AiFunctionHelper.MapToFunctionDef(tool);
|
||||
functionDefs.Add(funDef);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using BotSharp.Core.MCP.Settings;
|
||||
using ModelContextProtocol.Client;
|
||||
|
||||
namespace BotSharp.Core.MCP.Managers;
|
||||
|
||||
public class McpClientManager : IDisposable
|
||||
{
|
||||
|
||||
private readonly McpSettings mcpSettings;
|
||||
|
||||
public McpClientManager(McpSettings settings)
|
||||
{
|
||||
mcpSettings = settings;
|
||||
}
|
||||
|
||||
public async Task<IMcpClient> GetMcpClientAsync(string serverId)
|
||||
{
|
||||
return await McpClientFactory.CreateAsync(
|
||||
mcpSettings.McpServerConfigs.Where(x=> x.Name == serverId).First(),
|
||||
mcpSettings.McpClientOptions);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Configuration;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BotSharp.Core.Mcp.Settings;
|
||||
namespace BotSharp.Core.MCP.Settings;
|
||||
|
||||
public class MCPSettings
|
||||
public class McpSettings
|
||||
{
|
||||
public McpClientOptions McpClientOptions { get; set; }
|
||||
|
||||
public List<McpServerConfig> McpServerConfigs { get; set; } = new();
|
||||
|
||||
}
|
||||
16
src/Infrastructure/BotSharp.Core.MCP/Using.cs
Normal file
16
src/Infrastructure/BotSharp.Core.MCP/Using.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Linq;
|
||||
global using System.Threading.Tasks;
|
||||
global using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
global using BotSharp.Abstraction.Agents;
|
||||
global using BotSharp.Abstraction.Agents.Enums;
|
||||
global using BotSharp.Abstraction.Agents.Models;
|
||||
global using BotSharp.Abstraction.Agents.Settings;
|
||||
global using BotSharp.Abstraction.Conversations;
|
||||
global using BotSharp.Abstraction.Conversations.Models;
|
||||
global using BotSharp.Abstraction.Functions;
|
||||
global using BotSharp.Abstraction.Functions.Models;
|
||||
global using BotSharp.Abstraction.Utilities;
|
||||
|
||||
|
|
@ -72,9 +72,9 @@ public partial class AgentService
|
|||
hook.OnAgentUtilityLoaded(agent);
|
||||
}
|
||||
|
||||
if(agent.McpTools != null && agent.McpTools.Count >0)
|
||||
if(!agent.McpTools.IsNullOrEmpty())
|
||||
{
|
||||
hook.OnAgentMCPToolLoaded(agent);
|
||||
hook.OnAgentMcpToolLoaded(agent);
|
||||
}
|
||||
|
||||
hook.OnAgentLoaded(agent);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public partial class AgentService
|
|||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
|
||||
var template = agent.Templates.First(x => x.Name == templateName).Content;
|
||||
var template = agent.Templates.FirstOrDefault(x => x.Name == templateName)?.Content ?? string.Empty;
|
||||
|
||||
// update states
|
||||
foreach (var t in conv.States.GetStates())
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ public partial class AgentService
|
|||
.SetResponses(foundAgent.Responses)
|
||||
.SetSamples(foundAgent.Samples)
|
||||
.SetUtilities(foundAgent.Utilities)
|
||||
.SetMcps(foundAgent.McpTools)
|
||||
.SetMcpTools(foundAgent.McpTools)
|
||||
.SetKnowledgeBases(foundAgent.KnowledgeBases)
|
||||
.SetRules(foundAgent.Rules)
|
||||
.SetLlmConfig(foundAgent.LlmConfig);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ public static class BotSharpCoreExtensions
|
|||
{
|
||||
var pluginSettings = new PluginSettings();
|
||||
config.Bind("PluginLoader", pluginSettings);
|
||||
var excludedFunctions = pluginSettings.ExcludedFunctions ?? [];
|
||||
|
||||
services.AddScoped(provider =>
|
||||
{
|
||||
var settingService = provider.GetRequiredService<ISettingService>();
|
||||
|
|
@ -161,8 +163,9 @@ public static class BotSharpCoreExtensions
|
|||
|
||||
// Register function callback
|
||||
var functions = assembly.GetTypes()
|
||||
.Where(x => x.IsClass)
|
||||
.Where(x => x.GetInterface(nameof(IFunctionCallback)) != null)
|
||||
.Where(x => x.IsClass
|
||||
&& x.GetInterface(nameof(IFunctionCallback)) != null
|
||||
&& !excludedFunctions.Contains(x.Name))
|
||||
.ToArray();
|
||||
|
||||
foreach (var function in functions)
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ public partial class EvaluatingService
|
|||
|
||||
var query = "Please see yourself as a user and follow the instruction to generate a message.";
|
||||
var targetAgentId = request.AgentId;
|
||||
var evaluator = await agentService.GetAgent(BuiltInAgentId.Evaluator);
|
||||
var simulatorPrompt = evaluator.Templates.FirstOrDefault(x => x.Name == "instruction.simulator")?.Content ?? string.Empty;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -77,12 +75,13 @@ public partial class EvaluatingService
|
|||
|
||||
count++;
|
||||
|
||||
var result = await instructService.Instruct<SimulationResult>(simulatorPrompt, BuiltInAgentId.Evaluator,
|
||||
var result = await instructService.Instruct<SimulationResult>(query,
|
||||
new InstructOptions
|
||||
{
|
||||
Provider = request.Provider,
|
||||
Model = request.Model,
|
||||
Message = query,
|
||||
AgentId = BuiltInAgentId.Evaluator,
|
||||
TemplateName = "instruction.simulator",
|
||||
Data = new Dictionary<string, object>
|
||||
{
|
||||
{ "ref_conversation", refDialogs },
|
||||
|
|
@ -122,16 +121,14 @@ public partial class EvaluatingService
|
|||
var curDialogs = storage.GetDialogs(curConversationId);
|
||||
var curDialogContents = GetConversationContent(curDialogs);
|
||||
|
||||
var evaluator = await agentService.GetAgent(BuiltInAgentId.Evaluator);
|
||||
var metricPrompt = evaluator.Templates.FirstOrDefault(x => x.Name == "instruction.metrics")?.Content ?? string.Empty;
|
||||
var query = "Please follow the instruction for evaluation.";
|
||||
|
||||
var result = await instructService.Instruct<JsonDocument>(metricPrompt, BuiltInAgentId.Evaluator,
|
||||
var result = await instructService.Instruct<JsonDocument>(query,
|
||||
new InstructOptions
|
||||
{
|
||||
Provider = request.Provider,
|
||||
Model = request.Model,
|
||||
Message = query,
|
||||
AgentId = BuiltInAgentId.Evaluator,
|
||||
TemplateName = "instruction.metrics",
|
||||
Data = new Dictionary<string, object>
|
||||
{
|
||||
{ "ref_conversation", refDialogs },
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
using BotSharp.Abstraction.Instructs.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Files.Services;
|
||||
|
||||
public partial class FileInstructService
|
||||
{
|
||||
public async Task<string> SpeechToText(string? provider, string? model, InstructFileModel audio, string? text = null)
|
||||
public async Task<string> SpeechToText(InstructFileModel audio, string? text = null, InstructOptions? options = null)
|
||||
{
|
||||
var completion = CompletionProvider.GetAudioTranscriber(_services, provider: provider, model: model);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
text = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
}
|
||||
|
||||
var completion = CompletionProvider.GetAudioTranscriber(_services, provider: options?.Provider, model: options?.Model);
|
||||
var audioBytes = await DownloadFile(audio);
|
||||
using var stream = new MemoryStream();
|
||||
stream.Write(audioBytes, 0, audioBytes.Length);
|
||||
stream.Position = 0;
|
||||
|
||||
var fileName = $"{audio.FileName ?? "audio"}.{audio.FileExtension ?? "wav"}";
|
||||
var content = await completion.TranscriptTextAsync(stream, fileName, text);
|
||||
var content = await completion.TranscriptTextAsync(stream, fileName, text ?? string.Empty);
|
||||
stream.Close();
|
||||
return content;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,25 +6,28 @@ namespace BotSharp.Core.Files.Services;
|
|||
|
||||
public partial class FileInstructService
|
||||
{
|
||||
public async Task<string> ReadImages(string? provider, string? model, string text, IEnumerable<InstructFileModel> images, string? agentId = null)
|
||||
public async Task<string> ReadImages(string text, IEnumerable<InstructFileModel> images, InstructOptions? options = null)
|
||||
{
|
||||
var innerAgentId = agentId ?? Guid.Empty.ToString();
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: provider ?? "openai", model: model ?? "gpt-4o", multiModal: true);
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
var instruction = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: options?.Provider ?? "openai", model: options?.Model ?? "gpt-4o", multiModal: true);
|
||||
var message = await completion.GetChatCompletions(new Agent()
|
||||
{
|
||||
Id = innerAgentId,
|
||||
Instruction = instruction
|
||||
}, new List<RoleDialogModel>
|
||||
{
|
||||
new RoleDialogModel(AgentRole.User, text)
|
||||
{
|
||||
Files = images?.Select(x => new BotSharpFile { FileUrl = x.FileUrl, FileData = x.FileData }).ToList() ?? new List<BotSharpFile>()
|
||||
Files = images?.Select(x => new BotSharpFile { FileUrl = x.FileUrl, FileData = x.FileData }).ToList() ?? []
|
||||
}
|
||||
});
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -34,7 +37,9 @@ public partial class FileInstructService
|
|||
AgentId = innerAgentId,
|
||||
Provider = completion.Provider,
|
||||
Model = completion.Model,
|
||||
TemplateName = options?.TemplateName,
|
||||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
|
|
@ -42,19 +47,22 @@ public partial class FileInstructService
|
|||
return message.Content;
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> GenerateImage(string? provider, string? model, string text, string? agentId = null)
|
||||
public async Task<RoleDialogModel> GenerateImage(string text, InstructOptions? options = null)
|
||||
{
|
||||
var innerAgentId = agentId ?? Guid.Empty.ToString();
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-3");
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
var instruction = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: options?.Provider ?? "openai", model: options?.Model ?? "dall-e-3");
|
||||
var message = await completion.GetImageGeneration(new Agent()
|
||||
{
|
||||
Id = innerAgentId,
|
||||
Instruction = instruction
|
||||
}, new RoleDialogModel(AgentRole.User, text));
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -64,7 +72,9 @@ public partial class FileInstructService
|
|||
AgentId = innerAgentId,
|
||||
Provider = completion.Provider,
|
||||
Model = completion.Model,
|
||||
TemplateName = options?.TemplateName,
|
||||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
|
|
@ -72,15 +82,17 @@ public partial class FileInstructService
|
|||
return message;
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> VaryImage(string? provider, string? model, InstructFileModel image, string? agentId = null)
|
||||
public async Task<RoleDialogModel> VaryImage(InstructFileModel image, InstructOptions? options = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(image?.FileUrl) && string.IsNullOrWhiteSpace(image?.FileData))
|
||||
{
|
||||
throw new ArgumentException($"Cannot find image url or data!");
|
||||
}
|
||||
|
||||
var innerAgentId = agentId ?? Guid.Empty.ToString();
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-2");
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
var instruction = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: options?.Provider ?? "openai", model: options?.Model ?? "dall-e-2");
|
||||
var bytes = await DownloadFile(image);
|
||||
using var stream = new MemoryStream();
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
|
|
@ -89,7 +101,8 @@ public partial class FileInstructService
|
|||
var fileName = $"{image.FileName ?? "image"}.{image.FileExtension ?? "png"}";
|
||||
var message = await completion.GetImageVariation(new Agent()
|
||||
{
|
||||
Id = innerAgentId
|
||||
Id = innerAgentId,
|
||||
Instruction = instruction
|
||||
}, new RoleDialogModel(AgentRole.User, string.Empty), stream, fileName);
|
||||
|
||||
stream.Close();
|
||||
|
|
@ -97,7 +110,7 @@ public partial class FileInstructService
|
|||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -107,7 +120,9 @@ public partial class FileInstructService
|
|||
AgentId = innerAgentId,
|
||||
Provider = completion.Provider,
|
||||
Model = completion.Model,
|
||||
TemplateName = options?.TemplateName,
|
||||
UserMessage = string.Empty,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
|
|
@ -115,15 +130,17 @@ public partial class FileInstructService
|
|||
return message;
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> EditImage(string? provider, string? model, string text, InstructFileModel image, string? agentId = null)
|
||||
public async Task<RoleDialogModel> EditImage(string text, InstructFileModel image, InstructOptions? options = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(image?.FileUrl) && string.IsNullOrWhiteSpace(image?.FileData))
|
||||
{
|
||||
throw new ArgumentException($"Cannot find image url or data!");
|
||||
}
|
||||
|
||||
var innerAgentId = agentId ?? Guid.Empty.ToString();
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-2");
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
var instruction = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: options?.Provider ?? "openai", model: options?.Model ?? "dall-e-2");
|
||||
var bytes = await DownloadFile(image);
|
||||
using var stream = new MemoryStream();
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
|
|
@ -132,7 +149,8 @@ public partial class FileInstructService
|
|||
var fileName = $"{image.FileName ?? "image"}.{image.FileExtension ?? "png"}";
|
||||
var message = await completion.GetImageEdits(new Agent()
|
||||
{
|
||||
Id = innerAgentId
|
||||
Id = innerAgentId,
|
||||
Instruction = instruction
|
||||
}, new RoleDialogModel(AgentRole.User, text), stream, fileName);
|
||||
|
||||
stream.Close();
|
||||
|
|
@ -140,7 +158,7 @@ public partial class FileInstructService
|
|||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -150,7 +168,9 @@ public partial class FileInstructService
|
|||
AgentId = innerAgentId,
|
||||
Provider = completion.Provider,
|
||||
Model = completion.Model,
|
||||
TemplateName = options?.TemplateName,
|
||||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
|
|
@ -158,7 +178,7 @@ public partial class FileInstructService
|
|||
return message;
|
||||
}
|
||||
|
||||
public async Task<RoleDialogModel> EditImage(string? provider, string? model, string text, InstructFileModel image, InstructFileModel mask, string? agentId = null)
|
||||
public async Task<RoleDialogModel> EditImage(string text, InstructFileModel image, InstructFileModel mask, InstructOptions? options = null)
|
||||
{
|
||||
if ((string.IsNullOrWhiteSpace(image?.FileUrl) && string.IsNullOrWhiteSpace(image?.FileData)) ||
|
||||
(string.IsNullOrWhiteSpace(mask?.FileUrl) && string.IsNullOrWhiteSpace(mask?.FileData)))
|
||||
|
|
@ -166,8 +186,10 @@ public partial class FileInstructService
|
|||
throw new ArgumentException($"Cannot find image/mask url or data");
|
||||
}
|
||||
|
||||
var innerAgentId = agentId ?? Guid.Empty.ToString();
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-2");
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
var instruction = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: options?.Provider ?? "openai", model: options?.Model ?? "dall-e-2");
|
||||
var imageBytes = await DownloadFile(image);
|
||||
var maskBytes = await DownloadFile(mask);
|
||||
|
||||
|
|
@ -183,7 +205,8 @@ public partial class FileInstructService
|
|||
var maskName = $"{mask.FileName ?? "mask"}.{mask.FileExtension ?? "png"}";
|
||||
var message = await completion.GetImageEdits(new Agent()
|
||||
{
|
||||
Id = innerAgentId
|
||||
Id = innerAgentId,
|
||||
Instruction = instruction
|
||||
}, new RoleDialogModel(AgentRole.User, text), imageStream, imageName, maskStream, maskName);
|
||||
|
||||
imageStream.Close();
|
||||
|
|
@ -192,7 +215,7 @@ public partial class FileInstructService
|
|||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -202,7 +225,9 @@ public partial class FileInstructService
|
|||
AgentId = innerAgentId,
|
||||
Provider = completion.Provider,
|
||||
Model = completion.Model,
|
||||
TemplateName = options?.TemplateName,
|
||||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ namespace BotSharp.Core.Files.Services;
|
|||
|
||||
public partial class FileInstructService
|
||||
{
|
||||
public async Task<string> ReadPdf(string? provider, string? model, string? modelId, string prompt, List<InstructFileModel> files, string? agentId = null)
|
||||
public async Task<string> ReadPdf(string text, List<InstructFileModel> files, InstructOptions? options = null)
|
||||
{
|
||||
var content = string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(prompt) || files.IsNullOrEmpty())
|
||||
if (string.IsNullOrWhiteSpace(text) || files.IsNullOrEmpty())
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
|
@ -25,15 +25,18 @@ public partial class FileInstructService
|
|||
var images = await ConvertPdfToImages(pdfFiles);
|
||||
if (images.IsNullOrEmpty()) return content;
|
||||
|
||||
var innerAgentId = agentId ?? Guid.Empty.ToString();
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: provider ?? "openai",
|
||||
model: model, modelId: modelId ?? "gpt-4o", multiModal: true);
|
||||
var innerAgentId = options?.AgentId ?? Guid.Empty.ToString();
|
||||
var instruction = await GetAgentTemplate(innerAgentId, options?.TemplateName);
|
||||
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: options?.Provider ?? "openai",
|
||||
model: options?.Model ?? "gpt-4o", multiModal: true);
|
||||
var message = await completion.GetChatCompletions(new Agent()
|
||||
{
|
||||
Id = innerAgentId,
|
||||
Instruction = instruction
|
||||
}, new List<RoleDialogModel>
|
||||
{
|
||||
new RoleDialogModel(AgentRole.User, prompt)
|
||||
new RoleDialogModel(AgentRole.User, text)
|
||||
{
|
||||
Files = images.Select(x => new BotSharpFile { FileStorageUrl = x }).ToList()
|
||||
}
|
||||
|
|
@ -42,7 +45,7 @@ public partial class FileInstructService
|
|||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -52,7 +55,9 @@ public partial class FileInstructService
|
|||
AgentId = innerAgentId,
|
||||
Provider = completion.Provider,
|
||||
Model = completion.Model,
|
||||
UserMessage = prompt,
|
||||
TemplateName = options?.TemplateName,
|
||||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,4 +30,22 @@ public partial class FileInstructService : IFileInstructService
|
|||
_fileStorage.CreateDirectory(dir);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string?> GetAgentTemplate(string agentId, string? templateName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(agentId) || string.IsNullOrWhiteSpace(templateName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agent = await agentService.GetAgent(agentId);
|
||||
if (agent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var instruction = agentService.RenderedTemplate(agent, templateName);
|
||||
return instruction;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ namespace BotSharp.Core.Instructs;
|
|||
|
||||
public partial class InstructService
|
||||
{
|
||||
public async Task<InstructResult> Execute(string agentId, RoleDialogModel message, string? templateName = null, string? instruction = null)
|
||||
public async Task<InstructResult> Execute(string agentId, RoleDialogModel message,
|
||||
string? templateName = null, string? instruction = null, IEnumerable<InstructFileModel>? files = null)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
Agent agent = await agentService.LoadAgent(agentId);
|
||||
|
|
@ -88,7 +89,8 @@ public partial class InstructService
|
|||
new RoleDialogModel(AgentRole.User, prompt)
|
||||
{
|
||||
CurrentAgentId = agentId,
|
||||
MessageId = message.MessageId
|
||||
MessageId = message.MessageId,
|
||||
Files = files?.Select(x => new BotSharpFile { FileUrl = x.FileUrl, FileData = x.FileData }).ToList() ?? []
|
||||
}
|
||||
});
|
||||
response.Text = result.Content;
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ namespace BotSharp.Core.Instructs;
|
|||
|
||||
public partial class InstructService
|
||||
{
|
||||
public async Task<T?> Instruct<T>(string instruction, string agentId, InstructOptions options) where T : class
|
||||
public async Task<T?> Instruct<T>(string text, InstructOptions? options = null) where T : class
|
||||
{
|
||||
var prompt = GetPrompt(instruction, options.Data);
|
||||
var response = await GetAiResponse(agentId, prompt, options);
|
||||
var agent = await BuildInnerAgent(options);
|
||||
var response = await GetAiResponse(text, agent, options);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(response.Content)) return null;
|
||||
|
||||
|
|
@ -28,19 +28,18 @@ public partial class InstructService
|
|||
}
|
||||
else if (IsListType(type))
|
||||
{
|
||||
var text = response.Content.JsonArrayContent();
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
var content = response.Content.JsonArrayContent();
|
||||
if (!string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
|
||||
result = JsonSerializer.Deserialize<T>(text, botsharpOptions.JsonSerializerOptions);
|
||||
result = JsonSerializer.Deserialize<T>(content, botsharpOptions.JsonSerializerOptions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var text = response.Content.JsonContent();
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
var content = response.Content.JsonContent();
|
||||
if (!string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
result = JsonSerializer.Deserialize<T>(text, botsharpOptions.JsonSerializerOptions);
|
||||
result = JsonSerializer.Deserialize<T>(content, botsharpOptions.JsonSerializerOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -52,47 +51,62 @@ public partial class InstructService
|
|||
return result;
|
||||
}
|
||||
|
||||
private string GetPrompt(string instruction, Dictionary<string, object> data)
|
||||
private async Task<Agent> BuildInnerAgent(InstructOptions? options)
|
||||
{
|
||||
Agent? agent = null;
|
||||
string? instruction = null;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options?.AgentId))
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
agent = await agentService.GetAgent(options.AgentId);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options?.TemplateName))
|
||||
{
|
||||
var template = agent?.Templates?.FirstOrDefault(x => x.Name == options.TemplateName)?.Content ?? string.Empty;
|
||||
instruction = BuildInstruction(template, options?.Data ?? []);
|
||||
}
|
||||
}
|
||||
|
||||
return new Agent
|
||||
{
|
||||
Id = agent?.Id ?? Guid.Empty.ToString(),
|
||||
Name = agent?.Name ?? "Unknown",
|
||||
Instruction = instruction,
|
||||
LlmConfig = agent?.LlmConfig ?? new()
|
||||
};
|
||||
}
|
||||
|
||||
private string BuildInstruction(string instruction, Dictionary<string, object> data)
|
||||
{
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
|
||||
return render.Render(instruction, data ?? new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
private async Task<RoleDialogModel> GetAiResponse(string agentId, string prompt, InstructOptions options)
|
||||
private async Task<RoleDialogModel> GetAiResponse(string text, Agent agent, InstructOptions? options)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agent = await agentService.LoadAgent(agentId);
|
||||
|
||||
var localAgent = new Agent
|
||||
{
|
||||
Id = agentId,
|
||||
Name = agent?.Name ?? "Unknown",
|
||||
Instruction = prompt,
|
||||
TemplateDict = new()
|
||||
};
|
||||
|
||||
var messages = BuildDialogs(options);
|
||||
var provider = options.Provider ?? agent?.LlmConfig?.Provider ?? "openai";
|
||||
var model = options.Model ?? agent?.LlmConfig?.Model ?? "gpt-4o";
|
||||
var dialogs = BuildDialogs(text, options);
|
||||
var provider = options?.Provider ?? agent?.LlmConfig?.Provider ?? "openai";
|
||||
var model = options?.Model ?? agent?.LlmConfig?.Model ?? "gpt-4o";
|
||||
var completion = CompletionProvider.GetChatCompletion(_services, provider: provider, model: model);
|
||||
return await completion.GetChatCompletions(localAgent, messages);
|
||||
return await completion.GetChatCompletions(agent, dialogs);
|
||||
}
|
||||
|
||||
private List<RoleDialogModel> BuildDialogs(InstructOptions options)
|
||||
private List<RoleDialogModel> BuildDialogs(string text, InstructOptions? options)
|
||||
{
|
||||
var messages = new List<RoleDialogModel>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.ConversationId))
|
||||
if (!string.IsNullOrWhiteSpace(options?.ConversationId))
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var dialogs = conv.GetDialogHistory();
|
||||
messages.AddRange(dialogs);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.Message))
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
messages.Add(new RoleDialogModel(AgentRole.User, options.Message));
|
||||
messages.Add(new RoleDialogModel(AgentRole.User, text));
|
||||
}
|
||||
|
||||
return messages;
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ namespace BotSharp.Core.Repository
|
|||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentMcpTools(string agentId, List<MCPTool> mcptools)
|
||||
private void UpdateAgentMcpTools(string agentId, List<McpTool> mcptools)
|
||||
{
|
||||
if (mcptools == null) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
using BotSharp.Core.Mcp.Settings;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ModelContextProtocol.Client;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BotSharp.Core.Mcp;
|
||||
|
||||
public class MCPClientManager : IDisposable
|
||||
{
|
||||
|
||||
private readonly MCPSettings mcpSettings;
|
||||
|
||||
public MCPClientManager(MCPSettings settings)
|
||||
{
|
||||
mcpSettings = settings;
|
||||
}
|
||||
|
||||
public async Task<IMcpClient> GetMcpClientAsync(string serverId)
|
||||
{
|
||||
return await McpClientFactory.CreateAsync(mcpSettings.McpServerConfigs
|
||||
.Where(x=> x.Name == serverId).First(), mcpSettings.McpClientOptions);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -47,8 +47,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
|
||||
<ProjectReference Include="..\BotSharp.MCP\BotSharp.MCP.csproj" />
|
||||
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
|
||||
|
||||
namespace BotSharp.OpenAPI.Controllers;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using BotSharp.Abstraction.Instructs;
|
|||
using BotSharp.Abstraction.Instructs.Models;
|
||||
using BotSharp.Core.Infrastructures;
|
||||
using BotSharp.OpenAPI.ViewModels.Instructs;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace BotSharp.OpenAPI.Controllers;
|
||||
|
||||
|
|
@ -36,7 +37,8 @@ public class InstructModeController : ControllerBase
|
|||
var result = await instructor.Execute(agentId,
|
||||
new RoleDialogModel(AgentRole.User, input.Text),
|
||||
templateName: input.Template,
|
||||
instruction: input.Instruction);
|
||||
instruction: input.Instruction,
|
||||
files: input.Files);
|
||||
|
||||
result.States = state.GetStates();
|
||||
|
||||
|
|
@ -96,6 +98,9 @@ public class InstructModeController : ControllerBase
|
|||
}, new List<RoleDialogModel>
|
||||
{
|
||||
new RoleDialogModel(AgentRole.User, input.Text)
|
||||
{
|
||||
Files = input.Files?.Select(x => new BotSharpFile { FileUrl = x.FileUrl, FileData = x.FileData }).ToList() ?? []
|
||||
}
|
||||
});
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
|
|
@ -131,7 +136,13 @@ public class InstructModeController : ControllerBase
|
|||
try
|
||||
{
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var content = await fileInstruct.ReadImages(input.Provider, input.Model, input.Text, input.Files, input.AgentId);
|
||||
var content = await fileInstruct.ReadImages(input.Text, input.Files, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
return content;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -144,7 +155,8 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
[HttpPost("/instruct/multi-modal/upload")]
|
||||
public async Task<MultiModalViewModel> MultiModalCompletion(IFormFile file, [FromForm] string text, [FromForm] string? provider = null,
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null, [FromForm] string? agentId = null)
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null,
|
||||
[FromForm] string? agentId = null, [FromForm] string? templateName = null)
|
||||
{
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
states?.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External));
|
||||
|
|
@ -158,7 +170,13 @@ public class InstructModeController : ControllerBase
|
|||
new InstructFileModel { FileData = data }
|
||||
};
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var content = await fileInstruct.ReadImages(provider, model, text, files, agentId);
|
||||
var content = await fileInstruct.ReadImages(text, files, new InstructOptions
|
||||
{
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
AgentId = agentId,
|
||||
TemplateName = templateName
|
||||
});
|
||||
viewModel.Content = content;
|
||||
return viewModel;
|
||||
}
|
||||
|
|
@ -183,7 +201,13 @@ public class InstructModeController : ControllerBase
|
|||
try
|
||||
{
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var message = await fileInstruct.GenerateImage(input.Provider, input.Model, input.Text, input.AgentId);
|
||||
var message = await fileInstruct.GenerateImage(input.Text, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
return imageViewModel;
|
||||
|
|
@ -214,7 +238,13 @@ public class InstructModeController : ControllerBase
|
|||
}
|
||||
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var message = await fileInstruct.VaryImage(input.Provider, input.Model, input.File, input.AgentId);
|
||||
var message = await fileInstruct.VaryImage(input.File, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
|
||||
|
|
@ -231,7 +261,8 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
[HttpPost("/instruct/image-variation/upload")]
|
||||
public async Task<ImageGenerationViewModel> ImageVariation(IFormFile file, [FromForm] string? provider = null,
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null, [FromForm] string? agentId = null)
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null,
|
||||
[FromForm] string? agentId = null, [FromForm] string? templateName = null)
|
||||
{
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
states?.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External));
|
||||
|
|
@ -239,20 +270,18 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
try
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
file.CopyTo(stream);
|
||||
stream.Position = 0;
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-2");
|
||||
var message = await completion.GetImageVariation(new Agent()
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var fileData = FileUtility.BuildFileDataFromFile(file);
|
||||
var message = await fileInstruct.VaryImage(new InstructFileModel { FileData = fileData }, new InstructOptions
|
||||
{
|
||||
Id = agentId ?? Guid.Empty.ToString()
|
||||
}, new RoleDialogModel(AgentRole.User, string.Empty), stream, file.FileName);
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
AgentId = agentId,
|
||||
TemplateName = templateName
|
||||
});
|
||||
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
stream.Close();
|
||||
|
||||
return imageViewModel;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -278,7 +307,13 @@ public class InstructModeController : ControllerBase
|
|||
{
|
||||
return new ImageGenerationViewModel { Message = "Error! Cannot find a valid image file!" };
|
||||
}
|
||||
var message = await fileInstruct.EditImage(input.Provider, input.Model, input.Text, input.File, input.AgentId);
|
||||
var message = await fileInstruct.EditImage(input.Text, input.File, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
return imageViewModel;
|
||||
|
|
@ -294,7 +329,8 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
[HttpPost("/instruct/image-edit/upload")]
|
||||
public async Task<ImageGenerationViewModel> ImageEdit(IFormFile file, [FromForm] string text, [FromForm] string? provider = null,
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null, [FromForm] string? agentId = null)
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null,
|
||||
[FromForm] string? agentId = null, [FromForm] string? templateName = null)
|
||||
{
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
|
|
@ -303,19 +339,17 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
try
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
file.CopyTo(stream);
|
||||
stream.Position = 0;
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-2");
|
||||
var message = await completion.GetImageEdits(new Agent()
|
||||
var fileData = FileUtility.BuildFileDataFromFile(file);
|
||||
var message = await fileInstruct.EditImage(text, new InstructFileModel { FileData = fileData }, new InstructOptions
|
||||
{
|
||||
Id = agentId ?? Guid.Empty.ToString()
|
||||
}, new RoleDialogModel(AgentRole.User, text), stream, file.FileName);
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
AgentId = agentId,
|
||||
TemplateName = templateName
|
||||
});
|
||||
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
stream.Close();
|
||||
|
||||
return imageViewModel;
|
||||
}
|
||||
|
|
@ -344,7 +378,13 @@ public class InstructModeController : ControllerBase
|
|||
{
|
||||
return new ImageGenerationViewModel { Message = "Error! Cannot find a valid image or mask!" };
|
||||
}
|
||||
var message = await fileInstruct.EditImage(input.Provider, input.Model, input.Text, image, mask, input.AgentId);
|
||||
var message = await fileInstruct.EditImage(input.Text, image, mask, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
return imageViewModel;
|
||||
|
|
@ -359,8 +399,9 @@ public class InstructModeController : ControllerBase
|
|||
}
|
||||
|
||||
[HttpPost("/instruct/image-mask-edit/upload")]
|
||||
public async Task<ImageGenerationViewModel> ImageMaskEdit(IFormFile image, IFormFile mask, [FromForm] string text, [FromForm] string? provider = null,
|
||||
[FromForm] string? model = null, [FromForm] List<MessageState>? states = null, [FromForm] string? agentId = null)
|
||||
public async Task<ImageGenerationViewModel> ImageMaskEdit(IFormFile image, IFormFile mask,
|
||||
[FromForm] string text, [FromForm] string? provider = null, [FromForm] string? model = null,
|
||||
[FromForm] List<MessageState>? states = null, [FromForm] string? agentId = null, [FromForm] string? templateName = null)
|
||||
{
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
|
|
@ -369,24 +410,20 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
try
|
||||
{
|
||||
using var imageStream = new MemoryStream();
|
||||
image.CopyTo(imageStream);
|
||||
imageStream.Position = 0;
|
||||
|
||||
using var maskStream = new MemoryStream();
|
||||
mask.CopyTo(maskStream);
|
||||
maskStream.Position = 0;
|
||||
|
||||
var completion = CompletionProvider.GetImageCompletion(_services, provider: provider ?? "openai", model: model ?? "dall-e-2");
|
||||
var message = await completion.GetImageEdits(new Agent()
|
||||
var imageData = FileUtility.BuildFileDataFromFile(image);
|
||||
var maskData = FileUtility.BuildFileDataFromFile(mask);
|
||||
var message = await fileInstruct.EditImage(text,
|
||||
new InstructFileModel { FileData = imageData },
|
||||
new InstructFileModel { FileData = maskData }, new InstructOptions
|
||||
{
|
||||
Id = agentId ?? Guid.Empty.ToString()
|
||||
}, new RoleDialogModel(AgentRole.User, text), imageStream, image.FileName, maskStream, mask.FileName);
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
AgentId = agentId,
|
||||
TemplateName = templateName
|
||||
});
|
||||
|
||||
imageViewModel.Content = message.Content;
|
||||
imageViewModel.Images = message.GeneratedImages.Select(x => ImageViewModel.ToViewModel(x)).ToList();
|
||||
imageStream.Close();
|
||||
maskStream.Close();
|
||||
|
||||
return imageViewModel;
|
||||
}
|
||||
|
|
@ -411,7 +448,13 @@ public class InstructModeController : ControllerBase
|
|||
try
|
||||
{
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var content = await fileInstruct.ReadPdf(input.Provider, input.Model, input.ModelId, input.Text, input.Files, input.AgentId);
|
||||
var content = await fileInstruct.ReadPdf(input.Text, input.Files, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
viewModel.Content = content;
|
||||
return viewModel;
|
||||
}
|
||||
|
|
@ -425,8 +468,9 @@ public class InstructModeController : ControllerBase
|
|||
}
|
||||
|
||||
[HttpPost("/instruct/pdf-completion/upload")]
|
||||
public async Task<PdfCompletionViewModel> PdfCompletion(IFormFile file, [FromForm] string text, [FromForm] string? provider = null,
|
||||
[FromForm] string? model = null, [FromForm] string? modelId = null, [FromForm] List<MessageState>? states = null, [FromForm] string? agentId = null)
|
||||
public async Task<PdfCompletionViewModel> PdfCompletion(IFormFile file, [FromForm] string text,
|
||||
[FromForm] string? provider = null, [FromForm] string? model = null, [FromForm] List<MessageState>? states = null,
|
||||
[FromForm] string? agentId = null, [FromForm] string? templateName = null)
|
||||
{
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
states?.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External));
|
||||
|
|
@ -441,7 +485,13 @@ public class InstructModeController : ControllerBase
|
|||
};
|
||||
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var content = await fileInstruct.ReadPdf(provider, model, modelId, text, files, agentId);
|
||||
var content = await fileInstruct.ReadPdf(text, files, new InstructOptions
|
||||
{
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
AgentId = agentId,
|
||||
TemplateName = templateName
|
||||
});
|
||||
viewModel.Content = content;
|
||||
return viewModel;
|
||||
}
|
||||
|
|
@ -471,7 +521,13 @@ public class InstructModeController : ControllerBase
|
|||
{
|
||||
return new SpeechToTextViewModel { Message = "Error! Cannot find a valid audio file!" };
|
||||
}
|
||||
var content = await fileInstruct.SpeechToText(input.Provider, input.Model, audio);
|
||||
var content = await fileInstruct.SpeechToText(audio, input.Text, new InstructOptions
|
||||
{
|
||||
Provider = input.Provider,
|
||||
Model = input.Model,
|
||||
AgentId = input.AgentId,
|
||||
TemplateName = input.TemplateName
|
||||
});
|
||||
viewModel.Content = content;
|
||||
return viewModel;
|
||||
}
|
||||
|
|
@ -485,8 +541,10 @@ public class InstructModeController : ControllerBase
|
|||
}
|
||||
|
||||
[HttpPost("/instruct/speech-to-text/upload")]
|
||||
public async Task<SpeechToTextViewModel> SpeechToText(IFormFile file, [FromForm] string? provider = null, [FromForm] string? model = null,
|
||||
[FromForm] string? text = null, [FromForm] List<MessageState>? states = null)
|
||||
public async Task<SpeechToTextViewModel> SpeechToText(IFormFile file,
|
||||
[FromForm] string? provider = null, [FromForm] string? model = null,
|
||||
[FromForm] string? text = null, [FromForm] List<MessageState>? states = null,
|
||||
[FromForm] string? agentId = null, [FromForm] string? templateName = null)
|
||||
{
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
|
|
@ -495,14 +553,16 @@ public class InstructModeController : ControllerBase
|
|||
|
||||
try
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
file.CopyTo(stream);
|
||||
stream.Position = 0;
|
||||
var auditData = FileUtility.BuildFileDataFromFile(file);
|
||||
var content = await fileInstruct.SpeechToText(new InstructFileModel { FileData = auditData }, text, new InstructOptions
|
||||
{
|
||||
Provider = provider,
|
||||
Model = model,
|
||||
AgentId = agentId,
|
||||
TemplateName = templateName
|
||||
});
|
||||
|
||||
var completion = CompletionProvider.GetAudioTranscriber(_services, provider: provider, model: model);
|
||||
var content = await completion.TranscriptTextAsync(stream, file.FileName, text);
|
||||
viewModel.Content = content;
|
||||
stream.Close();
|
||||
return viewModel;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class AgentCreationModel
|
|||
public int? MaxMessageCount { get; set; }
|
||||
|
||||
public List<AgentUtility> Utilities { get; set; } = new();
|
||||
public List<MCPTool> McpTools { get; set; } = new();
|
||||
public List<McpTool> McpTools { get; set; } = new();
|
||||
public List<RoutingRuleUpdateModel> RoutingRules { get; set; } = new();
|
||||
public List<AgentKnowledgeBase> KnowledgeBases { get; set; } = new();
|
||||
public List<AgentRule> Rules { get; set; } = new();
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class AgentUpdateModel
|
|||
/// <summary>
|
||||
/// McpTools
|
||||
/// </summary>
|
||||
public List<MCPTool>? McpTools { get; set; }
|
||||
public List<McpTool>? McpTools { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// knowledge bases
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ public class AgentViewModel
|
|||
[JsonPropertyName("merge_utility")]
|
||||
public bool MergeUtility { get; set; }
|
||||
public List<AgentUtility> Utilities { get; set; }
|
||||
public List<MCPTool> Acps { get; set; }
|
||||
|
||||
[JsonPropertyName("mcp_tools")]
|
||||
public List<McpTool> McpTools { get; set; }
|
||||
|
||||
[JsonPropertyName("knowledge_bases")]
|
||||
public List<AgentKnowledgeBase> KnowledgeBases { get; set; }
|
||||
|
|
@ -87,7 +89,7 @@ public class AgentViewModel
|
|||
Responses = agent.Responses ?? [],
|
||||
Samples = agent.Samples ?? [],
|
||||
Utilities = agent.Utilities ?? [],
|
||||
Acps = agent.McpTools ?? [],
|
||||
McpTools = agent.McpTools ?? [],
|
||||
KnowledgeBases = agent.KnowledgeBases ?? [],
|
||||
IsPublic= agent.IsPublic,
|
||||
Disabled = agent.Disabled,
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ public class InstructBaseRequest
|
|||
[JsonPropertyName("model")]
|
||||
public virtual string? Model { get; set; } = null;
|
||||
|
||||
[JsonPropertyName("model_id")]
|
||||
public virtual string? ModelId { get; set; } = null;
|
||||
|
||||
[JsonPropertyName("agent_id")]
|
||||
public virtual string? AgentId { get; set; }
|
||||
|
||||
[JsonPropertyName("template_name")]
|
||||
public virtual string? TemplateName { get; set; }
|
||||
|
||||
[JsonPropertyName("states")]
|
||||
public List<MessageState> States { get; set; } = new();
|
||||
public List<MessageState> States { get; set; } = [];
|
||||
}
|
||||
|
||||
public class MultiModalRequest : InstructBaseRequest
|
||||
|
|
@ -26,7 +26,7 @@ public class MultiModalRequest : InstructBaseRequest
|
|||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("files")]
|
||||
public List<InstructFileModel> Files { get; set; } = new();
|
||||
public List<InstructFileModel> Files { get; set; } = [];
|
||||
}
|
||||
|
||||
public class ImageGenerationRequest : InstructBaseRequest
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ public class InstructMessageModel : IncomingMessageModel
|
|||
public string? Instruction { get; set; }
|
||||
public override string Channel { get; set; } = ConversationChannel.OpenAPI;
|
||||
public string? Template { get; set; }
|
||||
public List<InstructFileModel> Files { get; set; } = [];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -16,4 +17,5 @@ public class IncomingInstructRequest : IncomingMessageModel
|
|||
public string? AgentId { get; set; }
|
||||
public string? Instruction { get; set; }
|
||||
public string? Template { get; set; }
|
||||
public List<InstructFileModel> Files { get; set; } = [];
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ public class AgentDocument : MongoBase
|
|||
public List<AgentResponseMongoElement> Responses { get; set; }
|
||||
public List<string> Samples { get; set; }
|
||||
public List<AgentUtilityMongoElement> Utilities { get; set; }
|
||||
public List<AgentMCPToolMongoElement> McpTools { get; set; }
|
||||
public List<AgentMcpToolMongoElement> McpTools { get; set; }
|
||||
public List<AgentKnowledgeBaseMongoElement> KnowledgeBases { get; set; }
|
||||
public List<string> Profiles { get; set; }
|
||||
public List<string> Labels { get; set; }
|
||||
|
|
|
|||
|
|
@ -3,34 +3,37 @@ using BotSharp.Abstraction.Agents.Models;
|
|||
namespace BotSharp.Plugin.MongoStorage.Models;
|
||||
|
||||
[BsonIgnoreExtraElements(Inherited = true)]
|
||||
public class AgentMCPToolMongoElement
|
||||
public class AgentMcpToolMongoElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string ServerId { get; set; }
|
||||
|
||||
public bool Disabled { get; set; }
|
||||
public List<McpFunctionMongoElement> Functions { get; set; } = [];
|
||||
|
||||
public static AgentMCPToolMongoElement ToMongoElement(MCPTool utility)
|
||||
public static AgentMcpToolMongoElement ToMongoElement(McpTool tool)
|
||||
{
|
||||
return new AgentMCPToolMongoElement
|
||||
return new AgentMcpToolMongoElement
|
||||
{
|
||||
Disabled = utility.Disabled,
|
||||
Functions = utility.Functions?.Select(x => new McpFunctionMongoElement(x.Name))?.ToList() ?? [],
|
||||
Name = tool.Name,
|
||||
ServerId = tool.ServerId,
|
||||
Disabled = tool.Disabled,
|
||||
Functions = tool.Functions?.Select(x => new McpFunctionMongoElement(x.Name))?.ToList() ?? [],
|
||||
};
|
||||
}
|
||||
|
||||
public static MCPTool ToDomainElement(AgentMCPToolMongoElement utility)
|
||||
public static McpTool ToDomainElement(AgentMcpToolMongoElement tool)
|
||||
{
|
||||
return new MCPTool
|
||||
return new McpTool
|
||||
{
|
||||
Disabled = utility.Disabled,
|
||||
Functions = utility.Functions?.Select(x => new MCPFunction(x.Name))?.ToList() ?? [],
|
||||
Name = tool.Name,
|
||||
ServerId = tool.ServerId,
|
||||
Disabled = tool.Disabled,
|
||||
Functions = tool.Functions?.Select(x => new McpFunction(x.Name))?.ToList() ?? [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[BsonIgnoreExtraElements(Inherited = true)]
|
||||
public class McpFunctionMongoElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
|
|||
|
|
@ -264,11 +264,11 @@ public partial class MongoRepository
|
|||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentMcpTools(string agentId, List<MCPTool> mcps)
|
||||
private void UpdateAgentMcpTools(string agentId, List<McpTool> mcps)
|
||||
{
|
||||
if (mcps == null) return;
|
||||
|
||||
var elements = mcps?.Select(x => AgentMCPToolMongoElement.ToMongoElement(x))?.ToList() ?? [];
|
||||
var elements = mcps?.Select(x => AgentMcpToolMongoElement.ToMongoElement(x))?.ToList() ?? [];
|
||||
|
||||
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
|
||||
var update = Builders<AgentDocument>.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.McpTools, agent.McpTools.Select(u => AgentMCPToolMongoElement.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() ?? [],
|
||||
McpTools = x.McpTools?.Select(u => AgentMCPToolMongoElement.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() ?? [],
|
||||
McpTools = agentDoc.McpTools?.Select(u => AgentMCPToolMongoElement.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() ?? []
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ namespace BotSharp.Plugin.OpenAI.Providers.Realtime;
|
|||
public interface IOpenAiRealtimeApi
|
||||
{
|
||||
[Post("/v1/realtime/sessions")]
|
||||
Task<RealtimeSession> GetSessionAsync(RealtimeSessionCreationRequest model, [Authorize("Bearer")] string token);
|
||||
Task<RealtimeSession> CreateSessionAsync(RealtimeSessionCreationRequest model, [Authorize("Bearer")] string token);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ public class RealTimeCompletionProvider : IRealTimeCompletion
|
|||
var settings = settingsService.GetSetting(Provider, args.Model ?? _model);
|
||||
|
||||
var api = _services.GetRequiredService<IOpenAiRealtimeApi>();
|
||||
var session = await api.GetSessionAsync(args, settings.ApiKey);
|
||||
var session = await api.CreateSessionAsync(args, settings.ApiKey);
|
||||
return session;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,17 +53,17 @@ public class SqlValidateFn : IFunctionCallback
|
|||
var instructService = _services.GetRequiredService<IInstructService>();
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
|
||||
var agent = await agentService.GetAgent(BuiltInAgentId.SqlDriver);
|
||||
var template = agent.Templates.FirstOrDefault(x => x.Name == "sql_statement_correctness")?.Content ?? string.Empty;
|
||||
|
||||
var query = "Correct SQL Statement and keep the comments/explanations";
|
||||
var ddl = states.GetState("table_ddls");
|
||||
|
||||
var correctedSql = await instructService.Instruct<string>(template, BuiltInAgentId.SqlDriver,
|
||||
var correctedSql = await instructService.Instruct<string>(query,
|
||||
new InstructOptions
|
||||
{
|
||||
Provider = agent?.LlmConfig?.Provider ?? "openai",
|
||||
Model = agent?.LlmConfig?.Model ?? "gpt-4o",
|
||||
Message = "Correct SQL Statement and keep the comments/explanations",
|
||||
Provider = "openai",
|
||||
Model = "gpt-4o",
|
||||
AgentId = BuiltInAgentId.SqlDriver,
|
||||
TemplateName = "sql_statement_correctness",
|
||||
Data = new Dictionary<string, object>
|
||||
{
|
||||
{ "original_sql", message.Content },
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
using BotSharp.Core;
|
||||
using BotSharp.Core.MCP;
|
||||
using BotSharp.OpenAPI;
|
||||
using BotSharp.Logger;
|
||||
using BotSharp.Plugin.ChatHub;
|
||||
using Serilog;
|
||||
using BotSharp.Abstraction.Messaging.JsonConverters;
|
||||
using StackExchange.Redis;
|
||||
using BotSharp.MCP;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\tests\BotSharp.Plugin.PizzaBot\BotSharp.Plugin.PizzaBot.csproj" />
|
||||
<ProjectReference Include="..\BotSharp.ServiceDefaults\BotSharp.ServiceDefaults.csproj" />
|
||||
<ProjectReference Include="..\Infrastructure\BotSharp.Core.MCP\BotSharp.Core.MCP.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="$(SolutionName)==BotSharp">
|
||||
|
|
@ -72,7 +73,6 @@
|
|||
<ProjectReference Include="..\Plugins\BotSharp.Plugin.MetaGLM\BotSharp.Plugin.MetaGLM.csproj" />
|
||||
<ProjectReference Include="..\Plugins\BotSharp.Plugin.Planner\BotSharp.Plugin.Planner.csproj" />
|
||||
<ProjectReference Include="..\Plugins\BotSharp.Plugin.TencentCos\BotSharp.Plugin.TencentCos.csproj" />
|
||||
<ProjectReference Include="..\Infrastructure\BotSharp.MCP\BotSharp.MCP.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -171,23 +171,25 @@
|
|||
"Model": "gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
//"MCPSettings": {
|
||||
// "McpClientOptions": {
|
||||
// "ClientInfo": {
|
||||
// "Name": "SimpleToolsBotsharp",
|
||||
// "Version": "1.0.0"
|
||||
// }
|
||||
// },
|
||||
// "McpServerConfigs": [
|
||||
// {
|
||||
// "Id": "PizzaServer",
|
||||
// "Name": "PizzaServer",
|
||||
// "TransportType": "sse",
|
||||
// "TransportOptions": [],
|
||||
// "Location": "http://localhost:58905/sse"
|
||||
// }
|
||||
// ]
|
||||
//},
|
||||
|
||||
"MCPSettings": {
|
||||
"McpClientOptions": {
|
||||
"ClientInfo": {
|
||||
"Name": "SimpleToolsBotsharp",
|
||||
"Version": "1.0.0"
|
||||
}
|
||||
},
|
||||
"McpServerConfigs": [
|
||||
{
|
||||
"Id": "PizzaServer",
|
||||
"Name": "PizzaServer",
|
||||
"TransportType": "sse",
|
||||
"TransportOptions": [],
|
||||
"Location": "http://localhost:58905/sse"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"Conversation": {
|
||||
"DataDir": "conversations",
|
||||
"ShowVerboseLog": false,
|
||||
|
|
@ -412,6 +414,7 @@
|
|||
"BotSharp.Core.SideCar",
|
||||
"BotSharp.Core.Crontab",
|
||||
"BotSharp.Core.Realtime",
|
||||
"BotSharp.Core.MCP",
|
||||
"BotSharp.Logger",
|
||||
"BotSharp.Plugin.MongoStorage",
|
||||
"BotSharp.Plugin.Dashboard",
|
||||
|
|
@ -439,6 +442,9 @@
|
|||
"BotSharp.Plugin.EmailHandler",
|
||||
"BotSharp.Plugin.AudioHandler",
|
||||
"BotSharp.Plugin.TencentCos"
|
||||
],
|
||||
"ExcludedFunctions": [
|
||||
"McpToolAdapter"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue