From 58a05007f7e3562b4ce916549ed60c5c5a442aed Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Wed, 19 Mar 2025 14:37:08 -0500 Subject: [PATCH 1/3] util-twilio-leave_voicemail --- .../BotSharp.Plugin.Twilio.csproj | 15 +---- .../Controllers/TwilioStreamController.cs | 29 +++++---- .../Controllers/TwilioVoiceController.cs | 3 +- .../Interfaces/ITwilioCallStatusHook.cs | 1 + .../Functions/LeaveVoicemailFn.cs | 59 +++++++++++++++++++ .../OutboundPhoneCallHandlerUtilityHook.cs | 6 +- .../LlmContexts/LeaveVoicemailArgs.cs | 12 ++++ .../util-twilio-leave_voicemail.json | 19 ++++++ .../util-twilio-hangup_phone_call.fn.liquid | 3 - .../util-twilio-outbound_phone_call.fn.liquid | 1 - 10 files changed, 116 insertions(+), 32 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/LeaveVoicemailFn.cs create mode 100644 src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/LlmContexts/LeaveVoicemailArgs.cs create mode 100644 src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-leave_voicemail.json delete mode 100644 src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-hangup_phone_call.fn.liquid delete mode 100644 src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-outbound_phone_call.fn.liquid diff --git a/src/Plugins/BotSharp.Plugin.Twilio/BotSharp.Plugin.Twilio.csproj b/src/Plugins/BotSharp.Plugin.Twilio/BotSharp.Plugin.Twilio.csproj index a3a00f98..775a9384 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/BotSharp.Plugin.Twilio.csproj +++ b/src/Plugins/BotSharp.Plugin.Twilio/BotSharp.Plugin.Twilio.csproj @@ -14,11 +14,12 @@ - - + + PreserveNewest + PreserveNewest @@ -31,12 +32,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - @@ -51,8 +46,4 @@ - - - - diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioStreamController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioStreamController.cs index 04133b4c..007281e6 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioStreamController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioStreamController.cs @@ -38,16 +38,6 @@ public class TwilioStreamController : TwilioController var twilio = _services.GetRequiredService(); VoiceResponse response = default!; - if (request.AnsweredBy == "machine_start" && - request.Direction == "outbound-api" && - request.InitAudioFile != null) - { - response = new VoiceResponse(); - var url = twilio.GetSpeechPath(request.ConversationId, request.InitAudioFile); - response.Play(new Uri(url)); - return TwiML(response); - } - var instruction = new ConversationalVoiceResponse { ConversationId = request.ConversationId, @@ -70,7 +60,24 @@ public class TwilioStreamController : TwilioController request.ConversationId = await InitConversation(request); instruction.ConversationId = request.ConversationId; - response = twilio.ReturnBidirectionalMediaStreamsInstructions(instruction); + + if (request.AnsweredBy == "machine_start" && + request.Direction == "outbound-api") + { + response = new VoiceResponse(); + + await HookEmitter.Emit(_services, async hook => + { + await hook.OnVoicemailStarting(request); + }); + + var url = twilio.GetSpeechPath(request.ConversationId, "voicemail.mp3"); + response.Play(new Uri(url)); + } + else + { + response = twilio.ReturnBidirectionalMediaStreamsInstructions(instruction); + } await HookEmitter.Emit(_services, async hook => { diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs index 0a898651..94a0b9f0 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Controllers/TwilioVoiceController.cs @@ -475,8 +475,7 @@ public class TwilioVoiceController : TwilioController if (request.CallStatus == "completed") { if (request.AnsweredBy == "machine_start" && - request.Direction == "outbound-api" && - request.InitAudioFile != null) + request.Direction == "outbound-api") { // voicemail await HookEmitter.Emit(_services, async hook => diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Interfaces/ITwilioCallStatusHook.cs b/src/Plugins/BotSharp.Plugin.Twilio/Interfaces/ITwilioCallStatusHook.cs index c9ed4710..0c9aa83e 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/Interfaces/ITwilioCallStatusHook.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/Interfaces/ITwilioCallStatusHook.cs @@ -8,4 +8,5 @@ public interface ITwilioCallStatusHook Task OnVoicemailLeft(ConversationalVoiceRequest request); Task OnUserDisconnected(ConversationalVoiceRequest request); Task OnRecordingCompleted(ConversationalVoiceRequest request); + Task OnVoicemailStarting(ConversationalVoiceRequest request); } diff --git a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/LeaveVoicemailFn.cs b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/LeaveVoicemailFn.cs new file mode 100644 index 00000000..50b09853 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Functions/LeaveVoicemailFn.cs @@ -0,0 +1,59 @@ +using BotSharp.Abstraction.Files; +using BotSharp.Abstraction.Routing; +using BotSharp.Core.Infrastructures; +using BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.LlmContexts; + +namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Functions; + +public class LeaveVoicemailFn : IFunctionCallback +{ + private readonly IServiceProvider _services; + private readonly ILogger _logger; + private readonly TwilioSetting _setting; + + public string Name => "util-twilio-leave_voicemail"; + public string Indication => "leaving a voicemail"; + + public LeaveVoicemailFn( + IServiceProvider services, + ILogger logger, + TwilioSetting setting) + { + _services = services; + _logger = logger; + _setting = setting; + } + + public async Task Execute(RoleDialogModel message) + { + var args = JsonSerializer.Deserialize(message.FunctionArgs); + + var fileStorage = _services.GetRequiredService(); + var routing = _services.GetRequiredService(); + var conversationId = routing.Context.ConversationId; + var states = _services.GetRequiredService(); + var callSid = states.GetState("twilio_call_sid"); + + if (string.IsNullOrEmpty(callSid)) + { + message.Content = "The call has not been initiated."; + _logger.LogError(message.Content); + return false; + } + + // Generate voice message audio + string initAudioFile = null; + if (!string.IsNullOrEmpty(args.VoicemailMessage)) + { + var completion = CompletionProvider.GetAudioCompletion(_services, "openai", "tts-1"); + var data = await completion.GenerateAudioFromTextAsync(args.VoicemailMessage); + initAudioFile = "voicemail.mp3"; + fileStorage.SaveSpeechFile(conversationId, initAudioFile, data); + } + + message.Content = args.VoicemailMessage; + message.StopCompletion = true; + + return true; + } +} diff --git a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Hooks/OutboundPhoneCallHandlerUtilityHook.cs b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Hooks/OutboundPhoneCallHandlerUtilityHook.cs index 14fce290..58999457 100644 --- a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Hooks/OutboundPhoneCallHandlerUtilityHook.cs +++ b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/Hooks/OutboundPhoneCallHandlerUtilityHook.cs @@ -10,6 +10,7 @@ public class OutboundPhoneCallHandlerUtilityHook : IAgentUtilityHook private static string TRANSFER_PHONE_CALL_FN = $"{PREFIX}transfer_phone_call"; private static string HANGUP_PHONE_CALL_FN = $"{PREFIX}hangup_phone_call"; private static string TEXT_MESSAGE_FN = $"{PREFIX}text_message"; + private static string LEAVE_VOICEMAIL_FN = $"{PREFIX}leave_voicemail"; public void AddUtilities(List utilities) { @@ -21,12 +22,11 @@ public class OutboundPhoneCallHandlerUtilityHook : IAgentUtilityHook new($"{OUTBOUND_PHONE_CALL_FN}"), new($"{TRANSFER_PHONE_CALL_FN}"), new($"{HANGUP_PHONE_CALL_FN}"), - new($"{TEXT_MESSAGE_FN}") + new($"{TEXT_MESSAGE_FN}"), + new($"{LEAVE_VOICEMAIL_FN}") ], Templates = [ - new($"{OUTBOUND_PHONE_CALL_FN}.fn"), - new($"{HANGUP_PHONE_CALL_FN}.fn") ] }; diff --git a/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/LlmContexts/LeaveVoicemailArgs.cs b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/LlmContexts/LeaveVoicemailArgs.cs new file mode 100644 index 00000000..85cc3913 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Twilio/OutboundPhoneCallHandler/LlmContexts/LeaveVoicemailArgs.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.LlmContexts; + +public class LeaveVoicemailArgs +{ + [JsonPropertyName("phone_number")] + public string PhoneNumber { get; set; } = null!; + + [JsonPropertyName("voicemail_message")] + public string VoicemailMessage { get; set; } = null!; +} diff --git a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-leave_voicemail.json b/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-leave_voicemail.json new file mode 100644 index 00000000..53307a83 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/util-twilio-leave_voicemail.json @@ -0,0 +1,19 @@ +{ + "name": "util-twilio-leave_voicemail", + "description": "If the user wants you to leave a voicemail.", + "visibility_expression": "{% if states.channel == 'phone' %}visible{% endif %}", + "parameters": { + "type": "object", + "properties": { + "voicemail_message": { + "type": "string", + "description": "User voicemail with details." + }, + "phone_number": { + "type": "string", + "description": "Phone number to callback." + } + }, + "required": [ "voicemail_message", "phone_number" ] + } +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-hangup_phone_call.fn.liquid b/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-hangup_phone_call.fn.liquid deleted file mode 100644 index 5e89cbd2..00000000 --- a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-hangup_phone_call.fn.liquid +++ /dev/null @@ -1,3 +0,0 @@ -{% if channel == 'phone' %} -** If user wants to end the phone call or conversation, ask user if there is anything else to help. If not, end the phone call. -{% endif %} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-outbound_phone_call.fn.liquid b/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-outbound_phone_call.fn.liquid deleted file mode 100644 index d8fa9131..00000000 --- a/src/Plugins/BotSharp.Plugin.Twilio/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/util-twilio-outbound_phone_call.fn.liquid +++ /dev/null @@ -1 +0,0 @@ -** Please call util-twilio-outbound_phone_call if user wants to make an outbound call. \ No newline at end of file From d6672cbdddd2bac39af643692be9ec3b82b99d98 Mon Sep 17 00:00:00 2001 From: Visagan Guruparan <103048@smsassist.com> Date: Wed, 19 Mar 2025 15:59:11 -0500 Subject: [PATCH 2/3] Update web driver to handle mutiple tasks per agent --- .../Infrastructures/Enums/StateConst.cs | 1 + .../Functions/ChangeCheckboxFn.cs | 2 +- .../Functions/ChangeListValueFn.cs | 2 +- .../Functions/CheckRadioButtonFn.cs | 2 +- .../Functions/ClickButtonFn.cs | 2 +- .../Functions/ClickElementFn.cs | 2 +- .../Functions/ExtractDataFn.cs | 2 +- .../Functions/GoToPageFn.cs | 4 ++-- .../Functions/HttpRequestFn.cs | 5 ++++- .../Functions/InputUserPasswordFn.cs | 2 +- .../Functions/InputUserTextFn.cs | 2 +- .../Functions/OpenBrowserFn.cs | 4 ++-- .../Functions/ScreenshotFn.cs | 2 +- .../Functions/ScrollPageFn.cs | 6 +++--- .../WebDriverService.GetMessageContext.cs | 20 +++++++++++++++++++ .../UtilFunctions/UtilWebActionOnElementFn.cs | 4 ++-- .../UtilFunctions/UtilWebCloseBrowserFn.cs | 5 ++--- .../UtilFunctions/UtilWebGoToPageFn.cs | 5 ++--- .../UtilFunctions/UtilWebLocateElementFn.cs | 4 ++-- .../WebDriverPlugin.cs | 2 +- 20 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.WebDriver/Services/WebDriverService.GetMessageContext.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs index 9db7c440..038699ac 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/Enums/StateConst.cs @@ -16,4 +16,5 @@ public class StateConst public const string SUB_CONVERSATION_ID = "sub_conversation_id"; public const string ORIGIN_CONVERSATION_ID = "origin_conversation_id"; + public const string WEB_DRIVER_TASK_ID = "web_driver_task_id"; } diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeCheckboxFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeCheckboxFn.cs index 139515cc..39be4f95 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeCheckboxFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeCheckboxFn.cs @@ -34,7 +34,7 @@ public class ChangeCheckboxFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs index 9de29293..22c7127d 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs @@ -34,7 +34,7 @@ public class ChangeListValueFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/CheckRadioButtonFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/CheckRadioButtonFn.cs index c8d88e48..9716b0f7 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/CheckRadioButtonFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/CheckRadioButtonFn.cs @@ -34,7 +34,7 @@ public class CheckRadioButtonFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs index b0bf22aa..05436bfc 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs @@ -34,7 +34,7 @@ public class ClickButtonFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickElementFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickElementFn.cs index 5388cb98..19f8e58d 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickElementFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickElementFn.cs @@ -34,7 +34,7 @@ public class ClickElementFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs index 6a390429..1e7afa41 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs @@ -28,7 +28,7 @@ public class ExtractDataFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/GoToPageFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/GoToPageFn.cs index fe69f9d1..a9303526 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/GoToPageFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/GoToPageFn.cs @@ -31,7 +31,7 @@ public class GoToPageFn : IFunctionCallback var result = await _browser.GoToPage(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, new PageActionArgs { @@ -45,7 +45,7 @@ public class GoToPageFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs index fff2c240..9aea9670 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/HttpRequestFn.cs @@ -1,3 +1,5 @@ +using BotSharp.Plugin.WebDriver.Services; + namespace BotSharp.Plugin.WebDriver.Functions; public class HttpRequestFn : IFunctionCallback @@ -20,12 +22,13 @@ public class HttpRequestFn : IFunctionCallback var args = JsonSerializer.Deserialize(message.FunctionArgs); var agentService = _services.GetRequiredService(); + var webDriverService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(message.CurrentAgentId); var result = await _browser.SendHttpRequest(new MessageInfo { AgentId = agent.Id, MessageId = message.MessageId, - ContextId = convService.ConversationId + ContextId = webDriverService.GetMessageContext(message) }, args); message.Content = result.IsSuccess ? diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs index d910519a..5085ae24 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs @@ -33,7 +33,7 @@ public class InputUserPasswordFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs index dab4c36f..2312df4f 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs @@ -39,7 +39,7 @@ public class InputUserTextFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs index 0beb80fc..631bd7a5 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs @@ -31,7 +31,7 @@ public class OpenBrowserFn : IFunctionCallback var msgInfo = new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }; var result = await _browser.LaunchBrowser(msgInfo, new BrowserActionArgs @@ -58,7 +58,7 @@ public class OpenBrowserFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScreenshotFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScreenshotFn.cs index 8fb4049d..5c58a69e 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScreenshotFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScreenshotFn.cs @@ -24,7 +24,7 @@ public class ScreenshotFn : IFunctionCallback message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); message.Content = "Took screenshot completed. You can take another screenshot if needed."; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScrollPageFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScrollPageFn.cs index 5907c0b4..b6ca139a 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScrollPageFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ScrollPageFn.cs @@ -20,12 +20,13 @@ public class ScrollPageFn : IFunctionCallback var args = JsonSerializer.Deserialize(message.FunctionArgs); var agentService = _services.GetRequiredService(); + var webDriverService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(message.CurrentAgentId); message.Data = await _browser.ScrollPage(new MessageInfo { AgentId = agent.Id, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, new PageActionArgs { @@ -35,13 +36,12 @@ public class ScrollPageFn : IFunctionCallback message.Content = "Scrolled. You can scroll more if needed."; - var webDriverService = _services.GetRequiredService(); var path = webDriverService.GetScreenshotFilePath(message.MessageId); message.Data = await _browser.ScreenshotAsync(new MessageInfo { AgentId = message.CurrentAgentId, - ContextId = convService.ConversationId, + ContextId = webDriverService.GetMessageContext(message), MessageId = message.MessageId }, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Services/WebDriverService.GetMessageContext.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Services/WebDriverService.GetMessageContext.cs new file mode 100644 index 00000000..a316999f --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Services/WebDriverService.GetMessageContext.cs @@ -0,0 +1,20 @@ +using BotSharp.Abstraction.Infrastructures.Enums; + +namespace BotSharp.Plugin.WebDriver.Services +{ + public partial class WebDriverService + { + public string GetMessageContext(RoleDialogModel message) + { + var states = _services.GetService(); + var convService = _services.GetRequiredService(); + var webDriverTaskId = states.GetState(StateConst.WEB_DRIVER_TASK_ID, ""); + var contextId = message.CurrentAgentId; + if (!string.IsNullOrWhiteSpace(webDriverTaskId)) + { + contextId = webDriverTaskId; + } + return contextId; + } + } +} diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebActionOnElementFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebActionOnElementFn.cs index 6b328b2c..8cb9119a 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebActionOnElementFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebActionOnElementFn.cs @@ -35,17 +35,17 @@ public class UtilWebActionOnElementFn : IFunctionCallback var conv = _services.GetRequiredService(); var browser = _services.GetRequiredService(); + var webDriverService = _services.GetRequiredService(); var msg = new MessageInfo { AgentId = message.CurrentAgentId, MessageId = message.MessageId, - ContextId = message.CurrentAgentId, + ContextId = webDriverService.GetMessageContext(message), }; var result = await browser.ActionOnElement(msg, locatorArgs, actionArgs); message.Content = $"{actionArgs.Action} executed {(result.IsSuccess ? "success" : "failed")}"; - var webDriverService = _services.GetRequiredService(); var path = webDriverService.GetScreenshotFilePath(message.MessageId); message.Data = await browser.ScreenshotAsync(msg, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebCloseBrowserFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebCloseBrowserFn.cs index 0d836b73..36badff3 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebCloseBrowserFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebCloseBrowserFn.cs @@ -18,20 +18,19 @@ public class UtilWebCloseBrowserFn : IFunctionCallback public async Task Execute(RoleDialogModel message) { var conv = _services.GetRequiredService(); - + var webDriverService = _services.GetRequiredService(); var browser = _services.GetRequiredService(); var msg = new MessageInfo { AgentId = message.CurrentAgentId, MessageId = message.MessageId, - ContextId = message.CurrentAgentId, + ContextId = webDriverService.GetMessageContext(message) }; await browser.CloseBrowser(message.CurrentAgentId); message.Content = $"Browser closed."; - var webDriverService = _services.GetRequiredService(); var path = webDriverService.GetScreenshotFilePath(message.MessageId); message.Data = await browser.ScreenshotAsync(msg, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebGoToPageFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebGoToPageFn.cs index 7a5d8f89..0c22d916 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebGoToPageFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebGoToPageFn.cs @@ -29,13 +29,13 @@ public class UtilWebGoToPageFn : IFunctionCallback args.WaitTime = _webDriver.DefaultWaitTime; var conv = _services.GetRequiredService(); - + var webDriverService = _services.GetRequiredService(); var browser = _services.GetRequiredService(); var msg = new MessageInfo { AgentId = message.CurrentAgentId, MessageId = message.MessageId, - ContextId = message.CurrentAgentId, + ContextId = webDriverService.GetMessageContext(message) }; if (!args.KeepBrowserOpen) { @@ -50,7 +50,6 @@ public class UtilWebGoToPageFn : IFunctionCallback message.Content = $"Open web page successfully."; - var webDriverService = _services.GetRequiredService(); var path = webDriverService.GetScreenshotFilePath(message.MessageId); message.Data = await browser.ScreenshotAsync(msg, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebLocateElementFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebLocateElementFn.cs index 8267f4ab..672ad6ad 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebLocateElementFn.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/UtilFunctions/UtilWebLocateElementFn.cs @@ -22,17 +22,17 @@ public class UtilWebLocateElementFn : IFunctionCallback locatorArgs.Highlight = true; var browser = _services.GetRequiredService(); + var webDriverService = _services.GetRequiredService(); var msg = new MessageInfo { AgentId = message.CurrentAgentId, MessageId = message.MessageId, - ContextId = message.CurrentAgentId, + ContextId = webDriverService.GetMessageContext(message) }; var result = await browser.LocateElement(msg, locatorArgs); message.Content = $"Locating element {(result.IsSuccess ? "success" : "failed")}"; - var webDriverService = _services.GetRequiredService(); var path = webDriverService.GetScreenshotFilePath(message.MessageId); message.Data = await browser.ScreenshotAsync(msg, path); diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs b/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs index 152ca030..68540d55 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs @@ -23,7 +23,7 @@ public class WebDriverPlugin : IBotSharpPlugin var settingService = provider.GetRequiredService(); return settings; }); - + services.AddSingleton(); services.AddScoped(); services.AddSingleton(); From 924630ce7fd2aef5deca80a1111d21cd5d149826 Mon Sep 17 00:00:00 2001 From: Visagan Guruparan <103048@smsassist.com> Date: Wed, 19 Mar 2025 21:59:19 -0500 Subject: [PATCH 3/3] Update code to singleton for WebBrowsing settings --- src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs b/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs index 68540d55..2f4f4f08 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/WebDriverPlugin.cs @@ -17,13 +17,7 @@ public class WebDriverPlugin : IBotSharpPlugin { var settings = new WebBrowsingSettings(); config.Bind("WebBrowsing", settings); - - services.AddScoped(provider => - { - var settingService = provider.GetRequiredService(); - return settings; - }); - services.AddSingleton(); + services.AddSingleton(x => settings); services.AddScoped(); services.AddSingleton();