diff --git a/src/Infrastructure/BotSharp.Abstraction/SideCar/Attributes/SideCarAttribute.cs b/src/Infrastructure/BotSharp.Abstraction/SideCar/Attributes/SideCarAttribute.cs index 833cb013..4426d71f 100644 --- a/src/Infrastructure/BotSharp.Abstraction/SideCar/Attributes/SideCarAttribute.cs +++ b/src/Infrastructure/BotSharp.Abstraction/SideCar/Attributes/SideCarAttribute.cs @@ -79,7 +79,7 @@ public class SideCarAttribute : AsyncMoAttribute object? res = null; var isHandled = false; - var enabled = instance != null && instance.IsEnabled() && method != null; + var enabled = instance != null && instance.IsEnabled && method != null; if (!enabled) { return (isHandled, value); @@ -112,7 +112,7 @@ public class SideCarAttribute : AsyncMoAttribute object? value = null; var isHandled = false; - var enabled = instance != null && instance.IsEnabled() && method != null; + var enabled = instance != null && instance.IsEnabled && method != null; if (!enabled) { return (isHandled, value); diff --git a/src/Infrastructure/BotSharp.Abstraction/SideCar/IConversationSideCar.cs b/src/Infrastructure/BotSharp.Abstraction/SideCar/IConversationSideCar.cs index 3c9bcfa4..81b0cf9c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/SideCar/IConversationSideCar.cs +++ b/src/Infrastructure/BotSharp.Abstraction/SideCar/IConversationSideCar.cs @@ -5,8 +5,8 @@ namespace BotSharp.Abstraction.SideCar; public interface IConversationSideCar { string Provider { get; } + bool IsEnabled { get; } - bool IsEnabled(); void AppendConversationDialogs(string conversationId, List messages); List GetConversationDialogs(string conversationId); void UpdateConversationBreakpoint(string conversationId, ConversationBreakpoint breakpoint); diff --git a/src/Infrastructure/BotSharp.Core.SideCar/Services/BotSharpConversationSideCar.cs b/src/Infrastructure/BotSharp.Core.SideCar/Services/BotSharpConversationSideCar.cs index e4996b06..d636fa71 100644 --- a/src/Infrastructure/BotSharp.Core.SideCar/Services/BotSharpConversationSideCar.cs +++ b/src/Infrastructure/BotSharp.Core.SideCar/Services/BotSharpConversationSideCar.cs @@ -14,7 +14,6 @@ limitations under the License. ******************************************************************************/ -using BotSharp.Abstraction.SideCar.Models; using BotSharp.Core.Infrastructures; namespace BotSharp.Core.SideCar.Services; @@ -31,6 +30,7 @@ public class BotSharpConversationSideCar : IConversationSideCar private string _conversationId = string.Empty; public string Provider => "botsharp"; + public bool IsEnabled => _enabled; public BotSharpConversationSideCar( IServiceProvider services, @@ -40,11 +40,6 @@ public class BotSharpConversationSideCar : IConversationSideCar _logger = logger; } - public bool IsEnabled() - { - return _enabled; - } - public void AppendConversationDialogs(string conversationId, List messages) { if (!IsValid(conversationId)) @@ -99,17 +94,22 @@ public class BotSharpConversationSideCar : IConversationSideCar top.State = new ConversationState(states); } - public async Task SendMessage(string agentId, string text, + public async Task SendMessage( + string agentId, + string text, PostbackMessageModel? postback = null, List? states = null, List? dialogs = null, SideCarOptions? options = null) { _sideCarOptions = options; + _logger.LogInformation($"Entering side car conversation..."); BeforeExecute(dialogs); var response = await InnerExecute(agentId, text, postback, states); AfterExecute(); + + _logger.LogInformation($"Existing side car conversation..."); return response; } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index ff61fde2..4c8178d8 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -159,7 +159,7 @@ public class ConversationStateService : IConversationStateService Reset(); var endNodes = new Dictionary(); - if (_sidecar?.IsEnabled() == true) + if (_sidecar?.IsEnabled == true) { return endNodes; } @@ -234,7 +234,7 @@ public class ConversationStateService : IConversationStateService public void Save() { - if (_conversationId == null || _sidecar?.IsEnabled() == true) + if (_conversationId == null || _sidecar?.IsEnabled == true) { return; } diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/ChatStreamMiddleware.cs b/src/Plugins/BotSharp.Plugin.ChatHub/ChatStreamMiddleware.cs index cba35a15..171bf0f2 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/ChatStreamMiddleware.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/ChatStreamMiddleware.cs @@ -62,6 +62,7 @@ public class ChatStreamMiddleware var hub = services.GetRequiredService(); var conn = hub.SetHubConnection(conversationId); conn.CurrentAgentId = agentId; + InitEvents(conn); // load conversation and state var convService = services.GetRequiredService(); @@ -128,6 +129,11 @@ public class ChatStreamMiddleware break; } + return (response.Event, data); + } + + private void InitEvents(RealtimeHubConnection conn) + { conn.OnModelMessageReceived = message => JsonSerializer.Serialize(new { @@ -147,7 +153,5 @@ public class ChatStreamMiddleware { @event = "clear" }); - - return (response.Event, data); } } diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs index a41abe87..3c7a675d 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs @@ -179,7 +179,7 @@ public class ChatHubConversationHook : ConversationHookBase private bool AllowSendingMessage() { var sidecar = _services.GetService(); - return sidecar == null || !sidecar.IsEnabled(); + return sidecar == null || !sidecar.IsEnabled; } private async Task InitClientConversation(string conversationId, ConversationDto conversation) diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs index 2e95cfa2..6838c284 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs @@ -329,17 +329,13 @@ public class GoogleRealTimeProvider : IRealTimeCompletion var words = new List(); HookEmitter.Emit(_services, hook => words.AddRange(hook.OnModelTranscriptPrompt(agent)), agent.Id); - var functions = request.Tools?.SelectMany(s => s.FunctionDeclarations).Select(x => + var functions = request.Tools?.SelectMany(s => s.FunctionDeclarations).Select(x => new FunctionDef { - var fn = new FunctionDef - { - Name = x.Name ?? string.Empty, - Description = x.Description ?? string.Empty, - Parameters = x.Parameters != null + Name = x.Name ?? string.Empty, + Description = x.Description ?? string.Empty, + Parameters = x.Parameters != null ? JsonSerializer.Deserialize(JsonSerializer.Serialize(x.Parameters)) : null - }; - return fn; }).ToArray(); await HookEmitter.Emit(_services, diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs index 92fa6f84..3a0902d6 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Realtime/RealTimeCompletionProvider.cs @@ -326,15 +326,11 @@ public class RealTimeCompletionProvider : IRealTimeCompletion var (prompt, messages, options) = PrepareOptions(agent, []); var instruction = messages.FirstOrDefault()?.Content.FirstOrDefault()?.Text ?? agent?.Description ?? string.Empty; - var functions = options.Tools.Select(x => + var functions = options.Tools.Select(x => new FunctionDef { - var fn = new FunctionDef - { - Name = x.FunctionName, - Description = x.FunctionDescription - }; - fn.Parameters = JsonSerializer.Deserialize(x.FunctionParameters); - return fn; + Name = x.FunctionName, + Description = x.FunctionDescription, + Parameters = JsonSerializer.Deserialize(x.FunctionParameters) }).ToArray(); var realtimeModelSettings = _services.GetRequiredService(); diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs index 07c4ad87..de58dca6 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioInboundController.cs @@ -53,25 +53,29 @@ public class TwilioInboundController : TwilioController instruction.SpeechPaths.Add(request.InitAudioFile); } + // Before creating session await HookEmitter.Emit(_services, async hook => { await hook.OnSessionCreating(request, instruction); }, request.AgentId); + var (agent, conversationId) = await InitConversation(request); request.ConversationId = conversationId.Id; instruction.AgentId = request.AgentId; instruction.ConversationId = request.ConversationId; + + // After creating session await HookEmitter.Emit(_services, async hook => { await hook.OnSessionCreated(request); }, request.AgentId); + if (twilio.MachineDetected(request)) { response = new VoiceResponse(); - await HookEmitter.Emit(_services, async hook => await hook.OnVoicemailStarting(request), request.AgentId); @@ -119,7 +123,7 @@ public class TwilioInboundController : TwilioController await Task.Delay(1500); await twilio.StartRecording(request.CallSid, request.AgentId, request.ConversationId); }); - } + } return TwiML(response); } @@ -204,7 +208,7 @@ public class TwilioInboundController : TwilioController storage.Append(conversation.Id, new RoleDialogModel(AgentRole.User, request.Intent) { - CurrentAgentId = conversation.Id, + CurrentAgentId = agent.Id, CreatedAt = DateTime.UtcNow }); }