From 3deb6deee53f331b200ff44dc54320be0b666dd3 Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Sun, 20 Apr 2025 08:05:20 -0500 Subject: [PATCH] Optimize realtime route_to_agent --- .../Hooks/RealtimeConversationHook.cs | 28 +++++++++---------- .../Services/TwilioService.cs | 1 - .../TwilioStreamMiddleware.cs | 20 ++++++------- .../util-twilio-hangup_phone_call.json | 6 +--- 4 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs b/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs index bb019996..85c7d24c 100644 --- a/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs +++ b/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.Utilities; -using BotSharp.Core.Infrastructures; namespace BotSharp.Core.Realtime.Hooks; @@ -40,33 +39,32 @@ public class RealtimeConversationHook : ConversationHookBase, IConversationHook if (message.FunctionName == "route_to_agent") { - var inst = JsonSerializer.Deserialize(message.FunctionArgs ?? "{}") ?? new(); - message.Content = $"I'm your AI assistant '{inst.AgentName}' to help with: '{inst.NextActionReason}'"; hub.HubConn.CurrentAgentId = routing.Context.GetCurrentAgentId(); - var instruction = await hub.Completer.UpdateSession(hub.HubConn); - await hub.Completer.InsertConversationItem(message); - await hub.Completer.TriggerModelInference($"{instruction}\r\n\r\nAssist user task: {inst.NextActionReason}"); + await hub.Completer.UpdateSession(hub.HubConn); + await hub.Completer.TriggerModelInference(); } else if (message.FunctionName == "util-routing-fallback_to_router") { - var inst = JsonSerializer.Deserialize(message.FunctionArgs ?? "{}") ?? new(); - message.Content = $"Returned to Router due to {inst.Reason}"; hub.HubConn.CurrentAgentId = routing.Context.GetCurrentAgentId(); - var instruction = await hub.Completer.UpdateSession(hub.HubConn); - await hub.Completer.InsertConversationItem(message); - await hub.Completer.TriggerModelInference(instruction); + await hub.Completer.UpdateSession(hub.HubConn); + await hub.Completer.TriggerModelInference(); } else { - // Clear cache to force to rebuild the agent instruction - Utilities.ClearCache(); - // Update session for changed states var instruction = await hub.Completer.UpdateSession(hub.HubConn); await hub.Completer.InsertConversationItem(message); - await hub.Completer.TriggerModelInference(instruction); + + if (message.StopCompletion) + { + await hub.Completer.TriggerModelInference($"Say to user: \"{message.Content}\""); + } + else + { + await hub.Completer.TriggerModelInference($"{instruction}\r\n\r\nResponse user based on function result"); + } } } } diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs index d93f39fb..a792f72d 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Services/TwilioService.cs @@ -141,7 +141,6 @@ public class TwilioService } else { - response.Pause(5); response.Say("Goodbye."); } diff --git a/src/Plugins/BotSharp.Plugin.Twilio/TwilioStreamMiddleware.cs b/src/Plugins/BotSharp.Plugin.Twilio/TwilioStreamMiddleware.cs index 1c6f525e..ce4ad144 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/TwilioStreamMiddleware.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/TwilioStreamMiddleware.cs @@ -94,6 +94,13 @@ public class TwilioStreamMiddleware } else if (eventType == "user_dtmf_receiving") { + // Send a Stop command to Twilio + string clearEvent = JsonSerializer.Serialize(new + { + @event = "clear", + streamSid = conn.StreamId + }); + await SendEventToUser(webSocket, clearEvent); } else if (eventType == "user_dtmf_received") { @@ -183,14 +190,6 @@ public class TwilioStreamMiddleware streamSid = response.StreamSid }); - /*if (response.Event == "dtmf") - { - // Send a Stop command to Twilio - string stopPlaybackCommand = "{ \"action\": \"stop_playback\" }"; - var stopBytes = Encoding.UTF8.GetBytes(stopPlaybackCommand); - webSocket.SendAsync(new ArraySegment(stopBytes), WebSocketMessageType.Text, true, CancellationToken.None); - }*/ - return (eventType, data); } @@ -225,7 +224,7 @@ public class TwilioStreamMiddleware var routing = _services.GetRequiredService(); var hookProvider = _services.GetRequiredService(); var agentService = _services.GetRequiredService(); - var agent = await agentService.LoadAgent(conn.CurrentAgentId); + var agent = await agentService.GetAgent(conn.CurrentAgentId); var dialogs = routing.Context.GetDialogs(); var convService = _services.GetRequiredService(); var conversation = await convService.GetConversation(conn.ConversationId); @@ -248,7 +247,6 @@ public class TwilioStreamMiddleware } await completer.InsertConversationItem(message); - var instruction = await completer.UpdateSession(conn); - await completer.TriggerModelInference($"{instruction}\r\n\r\nReply based on the user input: {message.Content}"); + await completer.TriggerModelInference($"Response based on the user input: {message.Content}"); } } diff --git a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-hangup_phone_call.json b/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-hangup_phone_call.json index 9f0320f3..61f68692 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-hangup_phone_call.json +++ b/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-hangup_phone_call.json @@ -8,12 +8,8 @@ "reason": { "type": "string", "description": "The reason why user wants to end the phone call." - }, - "response_content": { - "type": "string", - "description": "A response statement said to the user to politely and gratefully ending a conversation before hanging up." } }, - "required": [ "reason", "response_content" ] + "required": [ "reason" ] } } \ No newline at end of file