diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs index 61cb0f4d..bbcc51ab 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentField.cs @@ -16,7 +16,8 @@ public enum AgentField Template, Response, Sample, - LlmConfig + LlmConfig, + Tool } public enum AgentTaskField diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentTool.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentTool.cs new file mode 100644 index 00000000..875062f8 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentTool.cs @@ -0,0 +1,8 @@ +namespace BotSharp.Abstraction.Agents.Enums; + +public class AgentTool +{ + public const string FileAnalyzer = "file-analyzer"; + public const string ImageGenerator = "image-generator"; + public const string HttpHandler = "http-handler"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 7b48f452..c1f82e7b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -90,6 +90,12 @@ public class Agent public List Profiles { get; set; } = new List(); + /// + /// Useful tools + /// + public List Tools { get; set; } + = new List(); + /// /// Inherit from agent /// @@ -121,6 +127,7 @@ public class Agent Functions = agent.Functions, Responses = agent.Responses, Samples = agent.Samples, + Tools = agent.Tools, Knowledges = agent.Knowledges, IsPublic = agent.IsPublic, Disabled = agent.Disabled, @@ -162,6 +169,12 @@ public class Agent return this; } + public Agent SetTools(List tools) + { + Tools = tools ?? new List(); + return this; + } + public Agent SetResponses(List responses) { Responses = responses ?? new List(); ; diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 8434359e..9fd40c09 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -58,4 +58,6 @@ public interface IConversationService Task GetConversationSummary(IEnumerable conversationId); Task GetConversationRecordOrCreateNew(string agentId); + + bool IsConversationMode(); } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index daab8916..ecf2ecfa 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -1,8 +1,6 @@ -using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Repositories.Enums; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Enums; -using Microsoft.EntityFrameworkCore.Metadata; using System.IO; namespace BotSharp.Core.Agents.Services; @@ -34,6 +32,7 @@ public partial class AgentService record.Templates = agent.Templates ?? new List(); record.Responses = agent.Responses ?? new List(); record.Samples = agent.Samples ?? new List(); + record.Tools = agent.Tools ?? new List(); if (agent.LlmConfig != null && !agent.LlmConfig.IsInherit) { record.LlmConfig = agent.LlmConfig; @@ -95,6 +94,7 @@ public partial class AgentService .SetFunctions(foundAgent.Functions) .SetResponses(foundAgent.Responses) .SetSamples(foundAgent.Samples) + .SetTools(foundAgent.Tools) .SetLlmConfig(foundAgent.LlmConfig); _db.UpdateAgent(clonedAgent, AgentField.All); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 5142133a..c810790e 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -161,4 +161,9 @@ public partial class ConversationService : IConversationService return converation; } + + public bool IsConversationMode() + { + return !string.IsNullOrWhiteSpace(_conversationId); + } } diff --git a/src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs b/src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs index 4b70fd73..e114ceb6 100644 --- a/src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs +++ b/src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs @@ -1,5 +1,3 @@ -using System.Text.RegularExpressions; - namespace BotSharp.Core.Files.Hooks; public class AttachmentProcessingHook : AgentHookBase @@ -15,11 +13,11 @@ public class AttachmentProcessingHook : AgentHookBase public override void OnAgentLoaded(Agent agent) { - var fileService = _services.GetRequiredService(); var conv = _services.GetRequiredService(); - var hasConvFiles = fileService.HasConversationUserFiles(conv.ConversationId); + var isConvMode = conv.IsConversationMode(); + var isEnabled = !agent.Tools.IsNullOrEmpty() && agent.Tools.Contains(AgentTool.FileAnalyzer); - if (hasConvFiles) + if (isConvMode && isEnabled) { var (prompt, loadAttachmentFn) = GetLoadAttachmentFn(); if (loadAttachmentFn != null) diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs index 3488e0e7..89d5081d 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Agent.cs @@ -53,6 +53,9 @@ namespace BotSharp.Core.Repository case AgentField.LlmConfig: UpdateAgentLlmConfig(agent.Id, agent.LlmConfig); break; + case AgentField.Tool: + UpdateAgentTools(agent.Id, agent.Tools); + break; case AgentField.All: UpdateAgentAllFields(agent); break; @@ -145,6 +148,19 @@ namespace BotSharp.Core.Repository File.WriteAllText(agentFile, json); } + private void UpdateAgentTools(string agentId, List tools) + { + if (tools == null) return; + + var (agent, agentFile) = GetAgentFromFile(agentId); + if (agent == null) return; + + agent.Tools = tools; + agent.UpdatedDateTime = DateTime.UtcNow; + var json = JsonSerializer.Serialize(agent, _options); + File.WriteAllText(agentFile, json); + } + private void UpdateAgentRoutingRules(string agentId, List rules) { if (rules == null) return; @@ -271,6 +287,7 @@ namespace BotSharp.Core.Repository agent.Disabled = inputAgent.Disabled; agent.Type = inputAgent.Type; agent.Profiles = inputAgent.Profiles; + agent.Tools = inputAgent.Tools; agent.RoutingRules = inputAgent.RoutingRules; agent.LlmConfig = inputAgent.LlmConfig; agent.UpdatedDateTime = DateTime.UtcNow; diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs index b5f8ea82..4078fc03 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -43,6 +43,7 @@ public class AgentCreationModel /// Combine different Agents together to form a Profile. /// public List Profiles { get; set; } = new List(); + public List Tools { get; set; } = new List(); public List RoutingRules { get; set; } = new List(); public AgentLlmConfig? LlmConfig { get; set; } @@ -57,6 +58,7 @@ public class AgentCreationModel Functions = Functions, Responses = Responses, Samples = Samples, + Tools = Tools, IsPublic = IsPublic, Type = Type, Disabled = Disabled, diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs index 0a461ea6..ba331f85 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -25,6 +25,11 @@ public class AgentUpdateModel /// public List? Samples { get; set; } + /// + /// Tools + /// + public List? Tools { get; set; } + /// /// Functions /// @@ -71,6 +76,7 @@ public class AgentUpdateModel Templates = Templates ?? new List(), Functions = Functions ?? new List(), Responses = Responses ?? new List(), + Tools = Tools ?? new List(), LlmConfig = LlmConfig }; diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index 9d87a3e2..5faa1b98 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -17,6 +17,7 @@ public class AgentViewModel public List Functions { get; set; } public List Responses { get; set; } public List Samples { get; set; } + public List Tools { get; set; } [JsonPropertyName("is_public")] public bool IsPublic { get; set; } @@ -63,6 +64,7 @@ public class AgentViewModel Functions = agent.Functions, Responses = agent.Responses, Samples = agent.Samples, + Tools = agent.Tools, IsPublic= agent.IsPublic, Disabled = agent.Disabled, IconUrl = agent.IconUrl, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs index 8e2f4dd4..8e4395a1 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentDocument.cs @@ -14,6 +14,7 @@ public class AgentDocument : MongoBase public List Functions { get; set; } public List Responses { get; set; } public List Samples { get; set; } + public List Tools { get; set; } public bool IsPublic { get; set; } public bool Disabled { get; set; } public List Profiles { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs index 97ceee9f..abdfb21b 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Agent.cs @@ -57,6 +57,9 @@ public partial class MongoRepository case AgentField.LlmConfig: UpdateAgentLlmConfig(agent.Id, agent.LlmConfig); break; + case AgentField.Tool: + UpdateAgentTools(agent.Id, agent.Tools); + break; case AgentField.All: UpdateAgentAllFields(agent); break; @@ -218,6 +221,18 @@ public partial class MongoRepository _dc.Agents.UpdateOne(filter, update); } + private void UpdateAgentTools(string agentId, List tools) + { + if (tools == null) return; + + var filter = Builders.Filter.Eq(x => x.Id, agentId); + var update = Builders.Update + .Set(x => x.Tools, tools) + .Set(x => x.UpdatedTime, DateTime.UtcNow); + + _dc.Agents.UpdateOne(filter, update); + } + private void UpdateAgentLlmConfig(string agentId, AgentLlmConfig? config) { var llmConfig = AgentLlmConfigMongoElement.ToMongoElement(config); @@ -244,6 +259,7 @@ public partial class MongoRepository .Set(x => x.Functions, agent.Functions.Select(f => FunctionDefMongoElement.ToMongoElement(f)).ToList()) .Set(x => x.Responses, agent.Responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList()) .Set(x => x.Samples, agent.Samples) + .Set(x => x.Tools, agent.Tools) .Set(x => x.LlmConfig, AgentLlmConfigMongoElement.ToMongoElement(agent.LlmConfig)) .Set(x => x.IsPublic, agent.IsPublic) .Set(x => x.UpdatedTime, DateTime.UtcNow); @@ -369,6 +385,7 @@ public partial class MongoRepository .Select(r => AgentResponseMongoElement.ToMongoElement(r))? .ToList() ?? new List(), Samples = x.Samples ?? new List(), + Tools = x.Tools ?? new List(), IsPublic = x.IsPublic, Type = x.Type, InheritAgentId = x.InheritAgentId, @@ -458,6 +475,7 @@ public partial class MongoRepository .Select(r => AgentResponseMongoElement.ToDomainElement(r)) .ToList() : new List(), Samples = agentDoc.Samples ?? new List(), + Tools = agentDoc.Tools ?? new List(), IsPublic = agentDoc.IsPublic, Disabled = agentDoc.Disabled, Type = agentDoc.Type, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Transaction.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Transaction.cs index 470b1fb1..923cf5fd 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Transaction.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Transaction.cs @@ -53,6 +53,7 @@ public partial class MongoRepository .Select(r => AgentResponseMongoElement.ToMongoElement(r))? .ToList() ?? new List(), Samples = x.Samples ?? new List(), + Tools = x.Tools ?? new List(), IsPublic = x.IsPublic, Type = x.Type, InheritAgentId = x.InheritAgentId, @@ -77,6 +78,7 @@ public partial class MongoRepository .Set(x => x.Functions, agent.Functions) .Set(x => x.Responses, agent.Responses) .Set(x => x.Samples, agent.Samples) + .Set(x => x.Tools, agent.Tools) .Set(x => x.IsPublic, agent.IsPublic) .Set(x => x.Type, agent.Type) .Set(x => x.InheritAgentId, agent.InheritAgentId)