From 6ce664d618ef73bfcd194ec449e5d1be4d7e529a Mon Sep 17 00:00:00 2001 From: hchen Date: Wed, 27 Sep 2023 15:49:44 -0500 Subject: [PATCH 1/2] Format LLM functions. --- .../Agents/AgentHookBase.cs | 3 +- .../BotSharp.Abstraction/Agents/IAgentHook.cs | 4 +- .../Agents/Models/Agent.cs | 7 +- .../Functions/Models/FunctionDef.cs | 4 +- .../Functions/Models/FunctionParametersDef.cs | 21 ++++++ .../Functions/Models/ParameterPropertyDef.cs | 7 ++ .../Routing/IRoutingHandler.cs | 4 ++ .../Services/AgentService.CreateAgent.cs | 8 +-- .../Services/AgentService.UpdateAgent.cs | 3 +- .../Agents/Services/AgentService.cs | 3 +- .../BotSharpServiceCollectionExtensions.cs | 3 + .../Repository/FileRepository.cs | 12 ++-- .../BotSharp.Core/Routing/Hooks/AgentHook.cs | 16 +++++ .../Routing/RoutingService.InvokeAgent.cs | 69 +++++++++---------- .../ViewModels/Agents/AgentCreationModel.cs | 3 +- .../ViewModels/Agents/AgentUpdateModel.cs | 5 +- .../ViewModels/Agents/AgentViewModel.cs | 3 +- .../Providers/ChatCompletionProvider.cs | 17 +---- .../Collections/AgentCollection.cs | 3 +- .../Repository/MongoRepository.cs | 3 +- 20 files changed, 121 insertions(+), 77 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Functions/Models/ParameterPropertyDef.cs create mode 100644 src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs index 18b1b4c6..b7dac328 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Settings; +using BotSharp.Abstraction.Functions.Models; namespace BotSharp.Abstraction.Agents; @@ -34,7 +35,7 @@ public abstract class AgentHookBase : IAgentHook return true; } - public virtual bool OnFunctionsLoaded(ref List functions) + public virtual bool OnFunctionsLoaded(ref List functions) { _agent.Functions = functions; return true; diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs index 50d1be93..e695eb4f 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentHook.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Functions.Models; + namespace BotSharp.Abstraction.Agents; public interface IAgentHook @@ -15,7 +17,7 @@ public interface IAgentHook bool OnInstructionLoaded(string template, Dictionary dict); - bool OnFunctionsLoaded(ref List functions); + bool OnFunctionsLoaded(ref List functions); bool OnSamplesLoaded(ref string samples); diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index d3551296..91a89722 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Routing.Models; namespace BotSharp.Abstraction.Agents.Models; @@ -32,7 +33,7 @@ public class Agent /// Functions /// [JsonIgnore] - public List Functions { get; set; } + public List Functions { get; set; } = new List(); /// /// Responses @@ -102,9 +103,9 @@ public class Agent return this; } - public Agent SetFunctions(List functions) + public Agent SetFunctions(List functions) { - Functions = functions ?? new List(); + Functions = functions ?? new List(); return this; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs index 75b98fbc..c74ca533 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs @@ -1,12 +1,10 @@ -using System.Text.Json; - namespace BotSharp.Abstraction.Functions.Models; public class FunctionDef { public string Name { get; set; } public string Description { get; set; } - public JsonDocument Parameters { get; set; } + public FunctionParametersDef Parameters { get; set; } public override string ToString() { diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs new file mode 100644 index 00000000..a7e273d3 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionParametersDef.cs @@ -0,0 +1,21 @@ +using System.Text.Json; + +namespace BotSharp.Abstraction.Functions.Models; + +public class FunctionParametersDef +{ + [JsonPropertyName("type")] + public string Type { get; set; } = "object"; + + /// + /// ParameterPropertyDef + /// { + /// "field_name": {} + /// } + /// + [JsonPropertyName("properties")] + public JsonDocument Properties { get; set; } = JsonSerializer.Deserialize("{}"); + + [JsonPropertyName("required")] + public List Required { get; set; } = new List(); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/ParameterPropertyDef.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/ParameterPropertyDef.cs new file mode 100644 index 00000000..c1870d34 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/ParameterPropertyDef.cs @@ -0,0 +1,7 @@ +namespace BotSharp.Abstraction.Functions.Models; + +public class ParameterPropertyDef +{ + public string Type { get; set; } = "string"; + public string Description { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs index 6c26510c..b487620b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHandler.cs @@ -3,6 +3,10 @@ using BotSharp.Abstraction.Models; namespace BotSharp.Abstraction.Routing; +/// +/// The routing handler will be injected to Router's FUNCTIONS section of the system prompt +/// So the handler will be invoked by LLM autonomously. +/// public interface IRoutingHandler { string Name { get; } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs index d42e1da0..69c1c209 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.CreateAgent.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Repositories; using System.IO; @@ -114,14 +115,13 @@ public partial class AgentService return templates; } - private List FetchFunctionsFromFile(string fileDir) + private List FetchFunctionsFromFile(string fileDir) { var file = Path.Combine(fileDir, "functions.json"); - if (!File.Exists(file)) return new List(); + if (!File.Exists(file)) return new List(); var functionsJson = File.ReadAllText(file); - var functionDefs = JsonSerializer.Deserialize>(functionsJson, _options); - var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList(); + var functions = JsonSerializer.Deserialize>(functionsJson, _options); return functions; } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index f91fdef0..b6c9dbae 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Routing.Models; using System.IO; @@ -22,7 +23,7 @@ public partial class AgentService record.Profiles = agent.Profiles ?? new List(); record.RoutingRules = agent.RoutingRules ?? new List(); record.Instruction = agent.Instruction ?? string.Empty; - record.Functions = agent.Functions ?? new List(); + record.Functions = agent.Functions ?? new List(); record.Templates = agent.Templates ?? new List(); record.Responses = agent.Responses ?? new List(); diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs index 6b613503..28f9bdd2 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs @@ -27,7 +27,8 @@ public partial class AgentService : IAgentService { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - WriteIndented = true + WriteIndented = true, + AllowTrailingCommas = true }; } diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 35540c6d..cb42139a 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -10,6 +10,7 @@ using BotSharp.Core.Instructs; using BotSharp.Abstraction.Instructs; using BotSharp.Abstraction.Routing; using System.Reflection; +using BotSharp.Core.Routing.Hooks; namespace BotSharp.Core; @@ -63,6 +64,8 @@ public static class BotSharpServiceCollectionExtensions services.AddScoped(); services.AddScoped(); + services.AddScoped(); + return services; } diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index ecda379f..19a7d128 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -372,7 +372,7 @@ public class FileRepository : IBotSharpRepository File.WriteAllText(instructionFile, instruction); } - private void UpdateAgentFunctions(string agentId, List inputFunctions) + private void UpdateAgentFunctions(string agentId, List inputFunctions) { if (inputFunctions.IsNullOrEmpty()) return; @@ -385,8 +385,7 @@ public class FileRepository : IBotSharpRepository var functions = new List(); foreach (var function in inputFunctions) { - var functionDef = JsonSerializer.Deserialize(function, _options); - functions.Add(JsonSerializer.Serialize(functionDef, _options)); + functions.Add(JsonSerializer.Serialize(function, _options)); } var functionText = JsonSerializer.Serialize(functions, _options); @@ -730,14 +729,13 @@ public class FileRepository : IBotSharpRepository return instruction; } - private List FetchFunctions(string fileDir) + private List FetchFunctions(string fileDir) { var file = Path.Combine(fileDir, "functions.json"); - if (!File.Exists(file)) return new List(); + if (!File.Exists(file)) return new List(); var functionsJson = File.ReadAllText(file); - var functionDefs = JsonSerializer.Deserialize>(functionsJson, _options); - var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList(); + var functions = JsonSerializer.Deserialize>(functionsJson, _options); return functions; } diff --git a/src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs b/src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs new file mode 100644 index 00000000..006ff5a1 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs @@ -0,0 +1,16 @@ +using BotSharp.Abstraction.Functions.Models; + +namespace BotSharp.Core.Routing.Hooks; + +public class AgentHook : AgentHookBase +{ + public AgentHook(IServiceProvider services, AgentSettings settings) + : base(services, settings) + { + } + + public override bool OnFunctionsLoaded(ref List functions) + { + return base.OnFunctionsLoaded(ref functions); + } +} diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index c592fb31..ebb0d1c7 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -18,51 +18,48 @@ public partial class RoutingService var agent = await agentService.LoadAgent(agentId); var chatCompletion = CompletionProvider.GetChatCompletion(_services); + RoleDialogModel response = chatCompletion.GetChatCompletions(agent, Dialogs); - RoleDialogModel response = null; - await chatCompletion.GetChatCompletionsAsync(agent, Dialogs, - async msg => + if (response.Role == AgentRole.Function) + { + var fn = response; + // execute function + // Save states + SaveStateByArgs(JsonSerializer.Deserialize(fn.FunctionArgs)); + + var conversationService = _services.GetRequiredService(); + // Call functions + await conversationService.CallFunctions(fn); + + if (string.IsNullOrEmpty(fn.Content)) { - response = msg; - }, async fn => + fn.Content = fn.ExecutionResult; + } + + Dialogs.Add(fn); + + if (!fn.StopCompletion) { - // execute function - // Save states - SaveStateByArgs(JsonSerializer.Deserialize(fn.FunctionArgs)); - - var conversationService = _services.GetRequiredService(); - // Call functions - await conversationService.CallFunctions(fn); - - if (string.IsNullOrEmpty(fn.Content)) + // Find response template + var templateService = _services.GetRequiredService(); + var quickResponse = await templateService.RenderFunctionResponse(agent.Id, fn); + if (!string.IsNullOrEmpty(quickResponse)) { - fn.Content = fn.ExecutionResult; - } - - Dialogs.Add(fn); - - if (!fn.StopCompletion) - { - // Find response template - var templateService = _services.GetRequiredService(); - var quickResponse = await templateService.RenderFunctionResponse(agent.Id, fn); - if (!string.IsNullOrEmpty(quickResponse)) + response = new RoleDialogModel(AgentRole.Assistant, quickResponse) { - response = new RoleDialogModel(AgentRole.Assistant, quickResponse) - { - CurrentAgentId = agent.Id - }; - } - else - { - response = await InvokeAgent(fn.CurrentAgentId); - } + CurrentAgentId = agent.Id + }; } else { - response = fn; + response = await InvokeAgent(fn.CurrentAgentId); } - }); + } + else + { + response = fn; + } + } return response; } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs index 3857d82c..a6a5ad04 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentCreationModel.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Routing.Models; namespace BotSharp.OpenAPI.ViewModels.Agents; @@ -9,7 +10,7 @@ public class AgentCreationModel public string Description { get; set; } public string Instruction { get; set; } public List Templates { get; set; } - public List Functions { get; set; } + public List Functions { get; set; } public List Responses { get; set; } public bool IsPublic { get; set; } public bool AllowRouting { get; set; } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs index 38452740..c340b57a 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentUpdateModel.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Routing.Models; namespace BotSharp.OpenAPI.ViewModels.Agents; @@ -26,7 +27,7 @@ public class AgentUpdateModel /// /// Functions /// - public List? Functions { get; set; } + public List? Functions { get; set; } /// /// Routes @@ -61,7 +62,7 @@ public class AgentUpdateModel .ToList() ?? new List(), Instruction = Instruction ?? string.Empty, Templates = Templates ?? new List(), - Functions = Functions ?? new List(), + Functions = Functions ?? new List(), Responses = Responses ?? new List() }; diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index bf25ec64..8c78ebbe 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Routing.Models; namespace BotSharp.OpenAPI.ViewModels.Agents; @@ -10,7 +11,7 @@ public class AgentViewModel public string Description { get; set; } public string Instruction { get; set; } public List Templates { get; set; } - public List Functions { get; set; } + public List Functions { get; set; } public List Responses { get; set; } public bool IsPublic { get; set; } public bool AllowRouting { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index cffa69f7..13d196a0 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -84,17 +84,6 @@ public class ChatCompletionProvider : IChatCompletion return samples; } - public List GetFunctions(List functionsJson) - { - var functions = functionsJson?.Select(x => JsonSerializer.Deserialize(x, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - AllowTrailingCommas = true - }))?.ToList() ?? new List(); - - return functions; - } - public RoleDialogModel GetChatCompletions(Agent agent, List conversations) { var (client, deploymentModel) = GetClient(); @@ -263,8 +252,7 @@ public class ChatCompletionProvider : IChatCompletion chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Content)); } - var functions = GetFunctions(agent.Functions); - foreach (var function in functions) + foreach (var function in agent.Functions) { chatCompletionsOptions.Functions.Add(new FunctionDefinition { @@ -301,10 +289,11 @@ public class ChatCompletionProvider : IChatCompletion var convSetting = _services.GetRequiredService(); if (convSetting.ShowVerboseLog) { + _logger.LogInformation("VERBOSE COMPLETION MESSAGES"); var verbose = string.Join("\n", chatCompletionsOptions.Messages.Select(x => { return x.Role == ChatRole.Function ? - $"{x.Role}: {x.Name} {x.Content}" : + $"{x.Role}: {x.Name} => {x.Content}" : $"{x.Role}: {x.Content}"; })); diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs index ff555750..eec7a559 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/AgentCollection.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Plugin.MongoStorage.Models; namespace BotSharp.Plugin.MongoStorage.Collections; @@ -9,7 +10,7 @@ public class AgentCollection : MongoBase public string Description { get; set; } public string Instruction { get; set; } public List Templates { get; set; } - public List Functions { get; set; } + public List Functions { get; set; } public List Responses { get; set; } public bool IsPublic { get; set; } public bool AllowRouting { get; set; } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index 0e919fcb..d360429f 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; using BotSharp.Plugin.MongoStorage.Collections; @@ -441,7 +442,7 @@ public class MongoRepository : IBotSharpRepository _dc.Agents.UpdateOne(filter, update); } - private void UpdateAgentFunctions(string agentId, List functions) + private void UpdateAgentFunctions(string agentId, List functions) { if (functions.IsNullOrEmpty()) return; From 649cba561e6066bfdc31d4b3a029cf1f7a708dff Mon Sep 17 00:00:00 2001 From: hchen Date: Wed, 27 Sep 2023 22:31:58 -0500 Subject: [PATCH 2/2] print functions in verbose. --- .../Functions/Models/FunctionDef.cs | 2 +- .../Agents/Services/AgentService.LoadAgent.cs | 4 +--- .../BotSharpServiceCollectionExtensions.cs | 3 +-- .../Conversations/Services/TokenStatistics.cs | 2 +- .../BotSharp.Core/Routing/Hooks/AgentHook.cs | 16 -------------- .../Routing/Hooks/RoutingAgentHook.cs | 21 +++++++++++++++++++ .../Providers/ChatCompletionProvider.cs | 10 ++++++++- 7 files changed, 34 insertions(+), 24 deletions(-) delete mode 100644 src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs create mode 100644 src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs index c74ca533..153fb473 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Functions/Models/FunctionDef.cs @@ -4,7 +4,7 @@ public class FunctionDef { public string Name { get; set; } public string Description { get; set; } - public FunctionParametersDef Parameters { get; set; } + public FunctionParametersDef Parameters { get; set; } = new FunctionParametersDef(); public override string ToString() { diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs index 59926c43..553d6436 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs @@ -1,6 +1,4 @@ using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Routing; -using BotSharp.Abstraction.Routing.Settings; using BotSharp.Abstraction.Templating; namespace BotSharp.Core.Agents.Services; @@ -34,7 +32,7 @@ public partial class AgentService hook.OnInstructionLoaded(agent.Instruction, templateDict); } - if (!agent.Functions.IsNullOrEmpty()) + if (agent.Functions != null) { var functions = agent.Functions; hook.OnFunctionsLoaded(ref functions); diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index cb42139a..2d8852ed 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -9,7 +9,6 @@ using BotSharp.Abstraction.Templating; using BotSharp.Core.Instructs; using BotSharp.Abstraction.Instructs; using BotSharp.Abstraction.Routing; -using System.Reflection; using BotSharp.Core.Routing.Hooks; namespace BotSharp.Core; @@ -64,7 +63,7 @@ public static class BotSharpServiceCollectionExtensions services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); return services; } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs index 1654b357..b86364ea 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs @@ -51,7 +51,7 @@ public class TokenStatistics : ITokenStatistics public void PrintStatistics() { - var stats = $"Token Usage: {_promptTokenCount} prompt + {_completionTokenCount} completion = {Total} total tokens. One-Way cost: ${Cost:C4}, accumulated cost: ${AccumulatedCost:C4}. Model: {_model}"; + var stats = $"Token Usage: {_promptTokenCount} prompt + {_completionTokenCount} completion = {Total} total tokens. One-Way cost: {Cost:C4}, accumulated cost: {AccumulatedCost:C4}. [{_model}]"; #if DEBUG Console.WriteLine(stats, Color.DarkGray); #else diff --git a/src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs b/src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs deleted file mode 100644 index 006ff5a1..00000000 --- a/src/Infrastructure/BotSharp.Core/Routing/Hooks/AgentHook.cs +++ /dev/null @@ -1,16 +0,0 @@ -using BotSharp.Abstraction.Functions.Models; - -namespace BotSharp.Core.Routing.Hooks; - -public class AgentHook : AgentHookBase -{ - public AgentHook(IServiceProvider services, AgentSettings settings) - : base(services, settings) - { - } - - public override bool OnFunctionsLoaded(ref List functions) - { - return base.OnFunctionsLoaded(ref functions); - } -} diff --git a/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs new file mode 100644 index 00000000..17ed9c34 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingAgentHook.cs @@ -0,0 +1,21 @@ +using BotSharp.Abstraction.Functions.Models; + +namespace BotSharp.Core.Routing.Hooks; + +public class RoutingAgentHook : AgentHookBase +{ + public RoutingAgentHook(IServiceProvider services, AgentSettings settings) + : base(services, settings) + { + } + + public override bool OnFunctionsLoaded(ref List functions) + { + functions.Add(new FunctionDef + { + Name = "fallback_to_router", + Description = "If the user's request is beyond your capabilities, you can call this function for help." + }); + return base.OnFunctionsLoaded(ref functions); + } +} diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index 13d196a0..7a4b9914 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -290,7 +290,7 @@ public class ChatCompletionProvider : IChatCompletion if (convSetting.ShowVerboseLog) { _logger.LogInformation("VERBOSE COMPLETION MESSAGES"); - var verbose = string.Join("\n", chatCompletionsOptions.Messages.Select(x => + var verbose = string.Join("\r\n", chatCompletionsOptions.Messages.Select(x => { return x.Role == ChatRole.Function ? $"{x.Role}: {x.Name} => {x.Content}" : @@ -298,6 +298,14 @@ public class ChatCompletionProvider : IChatCompletion })); _logger.LogInformation(verbose); + + _logger.LogInformation("VERBOSE FUNCTIONS"); + verbose = string.Join("\r\n", chatCompletionsOptions.Functions.Select(x => + { + return $"{x.Name}: {x.Description}\r\n{x.Parameters}"; + })); + + _logger.LogInformation(verbose); } return chatCompletionsOptions;