Add send_http_request for web driver.

This commit is contained in:
Haiping Chen 2024-03-08 07:17:36 -06:00
parent 73f9f6d1e5
commit e7ab91b97f
32 changed files with 349 additions and 184 deletions

View file

@ -1,19 +0,0 @@
namespace BotSharp.Plugin.WebDriver.Drivers;
public interface IWebBrowser
{
Task<bool> LaunchBrowser(string conversationId, string? url);
Task<string> ScreenshotAsync(string conversationId, string path);
Task<bool> ScrollPageAsync(BrowserActionParams actionParams);
Task<bool> InputUserText(BrowserActionParams actionParams);
Task<bool> InputUserPassword(BrowserActionParams actionParams);
Task<bool> ClickButton(BrowserActionParams actionParams);
Task<bool> ClickElement(BrowserActionParams actionParams);
Task<bool> ChangeListValue(BrowserActionParams actionParams);
Task<bool> CheckRadioButton(BrowserActionParams actionParams);
Task<bool> ChangeCheckbox(BrowserActionParams actionParams);
Task<bool> GoToPage(string conversationId, string url);
Task<string> ExtractData(BrowserActionParams actionParams);
Task<T> EvaluateScript<T>(string conversationId, string script);
Task CloseBrowser(string conversationId);
}

View file

@ -27,7 +27,7 @@ public class PlaywrightInstance : IDisposable
if (_contexts.ContainsKey(id))
return;
string tempFolderPath = $"{Path.GetTempPath()}\\playwright\\{id}";
string tempFolderPath = $"{Path.GetTempPath()}\\playwright";
_contexts[id] = await _playwright.Chromium.LaunchPersistentContextAsync(tempFolderPath, new BrowserTypeLaunchPersistentContextOptions
{
#if DEBUG

View file

@ -0,0 +1,15 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<BrowserActionResult> ActionOnElement(MessageInfo message, ElementLocatingArgs location, ElementActionArgs action)
{
await _instance.Wait(message.ConversationId);
var result = await LocateElement(message, location);
if (result.IsSuccess)
{
await DoAction(message, action, result);
}
return result;
}
}

View file

@ -1,12 +1,13 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> ChangeCheckbox(BrowserActionParams actionParams)
public async Task<BrowserActionResult> ChangeCheckbox(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
// Retrieve the page raw html and infer the element path
@ -21,26 +22,30 @@ public partial class PlaywrightWebDriver
var elements = _instance.GetPage(actionParams.ConversationId).GetByText(regex);
var count = await elements.CountAsync();
var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}";
if (count == 0)
{
return false;
result.ErrorMessage = errorMessage;
return result;
}
else if (count > 1)
{
_logger.LogError($"Located multiple elements by {actionParams.Context.ElementText}");
result.ErrorMessage = $"Located multiple elements by {actionParams.Context.ElementText}";
_logger.LogError(result.ErrorMessage);
var allElements = await elements.AllAsync();
foreach (var element in allElements)
{
}
return false;
return result;
}
var parentElement = elements.Locator("..");
count = await parentElement.CountAsync();
if (count == 0)
{
return false;
result.ErrorMessage = errorMessage;
return result;
}
var id = await elements.GetAttributeAsync("for");
@ -56,12 +61,14 @@ public partial class PlaywrightWebDriver
if (count == 0)
{
return false;
result.ErrorMessage = errorMessage;
return result;
}
else if (count > 1)
{
_logger.LogError($"Located multiple elements by {actionParams.Context.ElementText}");
return false;
result.ErrorMessage = $"Located multiple elements by {actionParams.Context.ElementText}";
_logger.LogError(result.ErrorMessage);
return result;
}
try
@ -76,13 +83,15 @@ public partial class PlaywrightWebDriver
await elements.ClickAsync();
}
return true;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
return result;
}
}

View file

@ -1,11 +1,10 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> ChangeListValue(BrowserActionParams actionParams)
public async Task<BrowserActionResult> ChangeListValue(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
// Retrieve the page raw html and infer the element path
@ -102,13 +101,16 @@ public partial class PlaywrightWebDriver
element.style.visibility = 'hidden';
}", control);
}
return true;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
return result;
}
}

View file

@ -1,12 +1,10 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> CheckRadioButton(BrowserActionParams actionParams)
public async Task<BrowserActionResult> CheckRadioButton(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
// Retrieve the page raw html and infer the element path
@ -20,17 +18,20 @@ public partial class PlaywrightWebDriver
var regex = new Regex(regexExpression, RegexOptions.IgnoreCase);
var elements = _instance.GetPage(actionParams.ConversationId).GetByText(regex);
var count = await elements.CountAsync();
var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}";
if (count == 0)
{
return false;
result.ErrorMessage = errorMessage;
return result;
}
var parentElement = elements.Locator("..");
count = await parentElement.CountAsync();
if (count == 0)
{
return false;
result.ErrorMessage = errorMessage;
return result;
}
elements = parentElement.GetByText(new Regex($"{actionParams.Context.UpdateValue}", RegexOptions.IgnoreCase));
@ -39,7 +40,8 @@ public partial class PlaywrightWebDriver
if (count == 0)
{
return false;
result.ErrorMessage = errorMessage;
return result;
}
try
@ -47,13 +49,15 @@ public partial class PlaywrightWebDriver
// var label = await elements.GetAttributeAsync("for");
await elements.SetCheckedAsync(true);
return true;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
return result;
}
}

View file

@ -1,11 +1,10 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> ClickButton(BrowserActionParams actionParams)
public async Task<BrowserActionResult> ClickButton(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
// Find by text exactly match
@ -46,7 +45,9 @@ public partial class PlaywrightWebDriver
if (elements == null)
{
return false;
var errorMessage = $"Can't locate element by keyword {actionParams.Context.ElementName}";
result.ErrorMessage = errorMessage;
return result;
}
}
@ -55,13 +56,15 @@ public partial class PlaywrightWebDriver
await elements.ClickAsync();
await _instance.Wait(actionParams.ConversationId);
return true;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
return result;
}
private async Task<string> FilteredButtonHtml(string conversationId)

View file

@ -1,12 +1,10 @@
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> ClickElement(BrowserActionParams actionParams)
public async Task<BrowserActionResult> ClickElement(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
var page = _instance.GetPage(actionParams.ConversationId);
@ -44,7 +42,8 @@ public partial class PlaywrightWebDriver
if (count == 0)
{
_logger.LogError($"Can't locate element by keyword {actionParams.Context.ElementText}");
result.ErrorMessage = $"Can't locate element by keyword {actionParams.Context.ElementText}";
_logger.LogError(result.ErrorMessage);
}
else if (count == 1)
{
@ -54,19 +53,20 @@ public partial class PlaywrightWebDriver
// Triggered ajax
await _instance.Wait(actionParams.ConversationId);
return true;
result.IsSuccess = true;
}
else if (count > 1)
{
_logger.LogWarning($"Multiple elements are found by keyword {actionParams.Context.ElementText}");
result.ErrorMessage = $"Multiple elements are found by keyword {actionParams.Context.ElementText}";
_logger.LogWarning(result.ErrorMessage);
var all = await locator.AllAsync();
foreach (var element in all)
{
var content = await element.TextContentAsync();
var content = await element.InnerHTMLAsync();
_logger.LogWarning(content);
}
}
return false;
return result;
}
}

View file

@ -0,0 +1,15 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task DoAction(MessageInfo message, ElementActionArgs action, BrowserActionResult result)
{
var page = _instance.GetPage(message.ConversationId);
ILocator locator = page.Locator(result.Selector);
if (action.Action == "click")
{
await locator.ClickAsync();
}
}
}

View file

@ -1,24 +1,34 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> GoToPage(string conversationId, string url)
public async Task<BrowserActionResult> GoToPage(string conversationId, string url)
{
var result = new BrowserActionResult();
try
{
var response = await _instance.GetPage(conversationId).GotoAsync(url);
await _instance.GetPage(conversationId).WaitForLoadStateAsync(LoadState.DOMContentLoaded);
await _instance.GetPage(conversationId).WaitForLoadStateAsync(LoadState.NetworkIdle);
return response.Status == 200;
if (response.Status == 200)
{
var page = _instance.GetPage(conversationId);
result.Body = await page.ContentAsync();
result.IsSuccess = true;
}
else
{
result.ErrorMessage = response.StatusText;
}
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
return result;
}
}

View file

@ -0,0 +1,37 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<BrowserActionResult> SendHttpRequest(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
// Send AJAX request
string script = $@"
(async () => {{
const response = await fetch('{actionParams.Context.Url}', {{
method: 'POST',
headers: {{
'Content-Type': 'application/json'
}},
body: '{actionParams.Context.Payload}'
}});
return await response.json();
}})();
";
try
{
var response = await EvaluateScript<object>(actionParams.ConversationId, script);
result.IsSuccess = true;
result.Body = JsonSerializer.Serialize(response);
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return result;
}
}

View file

@ -1,11 +1,10 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> InputUserPassword(BrowserActionParams actionParams)
public async Task<BrowserActionResult> InputUserPassword(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
// Retrieve the page raw html and infer the element path
@ -17,20 +16,24 @@ public partial class PlaywrightWebDriver
if (password == null)
{
_logger.LogError($"Can't locate the password element by '{actionParams.Context.ElementName}'");
return false;
result.ErrorMessage = $"Can't locate the password element by '{actionParams.Context.ElementName}'";
_logger.LogError(result.ErrorMessage);
return result;
}
var config = _services.GetRequiredService<IConfiguration>();
try
{
await password.FillAsync(actionParams.Context.Password);
return true;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
return result;
}
}

View file

@ -1,11 +1,10 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> InputUserText(BrowserActionParams actionParams)
public async Task<BrowserActionResult> InputUserText(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
var page = _instance.GetPage(actionParams.ConversationId);
@ -46,8 +45,7 @@ public partial class PlaywrightWebDriver
locator = Locator(actionParams.ConversationId, htmlElementContextOut);
count = await locator.CountAsync();
}
if (count == 1)
else if (count > 0)
{
try
{
@ -59,15 +57,17 @@ public partial class PlaywrightWebDriver
// Triggered ajax
await _instance.Wait(actionParams.ConversationId);
return true;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
}
return false;
return result;
}
private async Task<string> FilteredInputHtml(string conversationId)

View file

@ -1,11 +1,13 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> LaunchBrowser(string conversationId, string? url)
public async Task<BrowserActionResult> LaunchBrowser(string conversationId, string? url)
{
var result = new BrowserActionResult()
{
IsSuccess = true
};
await _instance.InitInstance(conversationId);
if (!string.IsNullOrEmpty(url))
@ -21,16 +23,17 @@ public partial class PlaywrightWebDriver
Timeout = 15 * 1000
});
await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
return response.Status == 200;
result.IsSuccess = response.Status == 200;
}
catch(Exception ex)
{
result.ErrorMessage = ex.Message;
result.StackTrace = ex.StackTrace;
_logger.LogError(ex.Message);
}
return false;
}
}
return true;
return result;
}
}

View file

@ -0,0 +1,88 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<BrowserActionResult> LocateElement(MessageInfo message, ElementLocatingArgs location)
{
var result = new BrowserActionResult();
var page = _instance.GetPage(message.ConversationId);
ILocator locator = page.Locator("body");
int count = 0;
// check if selector is specified
if (location.Selector != null)
{
locator = page.Locator(location.Selector);
count = await locator.CountAsync();
}
// try attribute
if (count == 0 && !string.IsNullOrEmpty(location.AttributeName))
{
locator = locator.Locator($"[{location.AttributeName}='{location.AttributeValue}']");
count = await locator.CountAsync();
}
// Retrieve the page raw html and infer the element path
if (!string.IsNullOrEmpty(location.Text))
{
var regexExpression = location.MatchRule.ToLower() switch
{
"startwith" => $"^{location.Text}",
"endwith" => $"{location.Text}$",
"contains" => $"{location.Text}",
_ => $"^{location.Text}$"
};
var regex = new Regex(regexExpression, RegexOptions.IgnoreCase);
locator = locator.GetByText(regex);
count = await locator.CountAsync();
// try placeholder
if (count == 0)
{
locator = locator.GetByPlaceholder(regex);
count = await locator.CountAsync();
}
}
if (location.Index > 0)
{
locator = locator.Nth(location.Index);
count = await locator.CountAsync();
}
if (count == 0)
{
result.ErrorMessage = $"Can't locate element by keyword {location.Text}";
_logger.LogError(result.ErrorMessage);
}
else if (count == 1)
{
result.Selector = locator.ToString().Split('@').Last();
var text = await locator.InnerTextAsync();
result.Body = text;
result.IsSuccess = true;
}
else if (count > 1)
{
if (location.FailIfMultiple)
{
result.ErrorMessage = $"Multiple elements are found by {locator}";
_logger.LogError(result.ErrorMessage);
foreach (var element in await locator.AllAsync())
{
var content = await element.InnerHTMLAsync();
_logger.LogError(content);
}
}
else
{
result.Selector = locator.ToString();
result.IsSuccess = true;
}
}
return result;
}
}

View file

@ -1,19 +1,23 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<string> ScreenshotAsync(string conversationId, string path)
public async Task<BrowserActionResult> ScreenshotAsync(string conversationId, string path)
{
var result = new BrowserActionResult();
await _instance.Wait(conversationId);
var page = _instance.GetPage(conversationId);
await Task.Delay(500);
var bytes = await page.ScreenshotAsync(new PageScreenshotOptions
{
Path = path
Path = path,
FullPage = true
});
return "data:image/png;base64," + Convert.ToBase64String(bytes);
result.IsSuccess = true;
result.Body = "data:image/png;base64," + Convert.ToBase64String(bytes);
return result;
}
}

View file

@ -1,10 +1,10 @@
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver
{
public async Task<bool> ScrollPageAsync(BrowserActionParams actionParams)
public async Task<BrowserActionResult> ScrollPageAsync(BrowserActionParams actionParams)
{
var result = new BrowserActionResult();
await _instance.Wait(actionParams.ConversationId);
var page = _instance.GetPage(actionParams.ConversationId);
@ -18,6 +18,7 @@ public partial class PlaywrightWebDriver
else if (actionParams.Context.Direction == "right")
await page.EvaluateAsync("window.scrollBy(400, 0)");
return true;
result.IsSuccess = true;
return result;
}
}

View file

@ -1,5 +1,3 @@
using Microsoft.Extensions.Logging;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
public partial class PlaywrightWebDriver : IWebBrowser

View file

@ -24,9 +24,9 @@ public class ChangeCheckboxFn : IFunctionCallback
var result = await _browser.ChangeCheckbox(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
var content = $"{(args.UpdateValue == "check" ? "Check" : "Uncheck")} checkbox of '{args.ElementText}'";
message.Content = result ?
message.Content = result.IsSuccess ?
$"{content} successfully" :
$"{content} failed";
$"{content} failed. {result.ErrorMessage}";
var webDriverService = _services.GetRequiredService<WebDriverService>();
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -24,9 +24,9 @@ public class ChangeListValueFn : IFunctionCallback
var result = await _browser.ChangeListValue(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
var content = $"Change value to '{args.UpdateValue}' for {args.ElementName}";
message.Content = result ?
message.Content = result.IsSuccess ?
$"{content} successfully" :
$"{content} failed";
$"{content} failed. {result.ErrorMessage}";
var webDriverService = _services.GetRequiredService<WebDriverService>();
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -24,9 +24,9 @@ public class CheckRadioButtonFn : IFunctionCallback
var result = await _browser.CheckRadioButton(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
var content = $"Check value of '{args.UpdateValue}' for radio button '{args.ElementName}'";
message.Content = result ?
message.Content = result.IsSuccess ?
$"{content} successfully" :
$"{content} failed";
$"{content} failed. {result.ErrorMessage}";
var webDriverService = _services.GetRequiredService<WebDriverService>();
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -24,9 +24,9 @@ public class ClickButtonFn : IFunctionCallback
var result = await _browser.ClickButton(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
var content = $"Click button of '{args.ElementName}'";
message.Content = result ?
message.Content = result.IsSuccess ?
$"{content} successfully" :
$"{content} failed";
$"{content} failed. {result.ErrorMessage}";
var webDriverService = _services.GetRequiredService<WebDriverService>();
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -24,9 +24,9 @@ public class ClickElementFn : IFunctionCallback
var result = await _browser.ClickElement(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
var content = $"Click element {args.MatchRule} text '{args.ElementText}'";
message.Content = result ?
message.Content = result.IsSuccess ?
$"{content} successfully" :
$"{content} failed";
$"{content} failed. {result.ErrorMessage}";
var webDriverService = _services.GetRequiredService<WebDriverService>();
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -27,12 +27,12 @@ public class GoToPageFn : IFunctionCallback
url = url.Replace("https://https://", "https://");
var result = await _browser.GoToPage(convService.ConversationId, url);
message.Content = result ? $"Page {url} is open." : $"Page {url} open failed.";
message.Content = result.IsSuccess ? $"Page {url} is open." : $"Page {url} open failed. {result.ErrorMessage}";
var path = webDriverService.GetScreenshotFilePath(message.MessageId);
message.Data = await _browser.ScreenshotAsync(convService.ConversationId, path);
return result;
return result.IsSuccess;
}
}

View file

@ -0,0 +1,32 @@
namespace BotSharp.Plugin.WebDriver.Functions;
public class HttpRequestFn : IFunctionCallback
{
public string Name => "send_http_request";
private readonly IServiceProvider _services;
private readonly IWebBrowser _browser;
public HttpRequestFn(IServiceProvider services,
IWebBrowser browser)
{
_services = services;
_browser = browser;
}
public async Task<bool> Execute(RoleDialogModel message)
{
var convService = _services.GetRequiredService<IConversationService>();
var args = JsonSerializer.Deserialize<BrowsingContextIn>(message.FunctionArgs);
var agentService = _services.GetRequiredService<IAgentService>();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
var result = await _browser.SendHttpRequest(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
message.Content = result.IsSuccess ?
result.Body :
$"Http request failed. {result.ErrorMessage}";
return true;
}
}

View file

@ -26,7 +26,7 @@ public class InputUserPasswordFn : IFunctionCallback
args.Password = webDriverService.ReplaceToken(args.Password);
var result = await _browser.InputUserPassword(new BrowserActionParams(agent, args, convService.ConversationId, message.MessageId));
message.Content = result ? "Input password successfully" : "Input password failed";
message.Content = result.IsSuccess ? "Input password successfully" : "Input password failed";
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -29,9 +29,9 @@ public class InputUserTextFn : IFunctionCallback
content += " and pressed Enter";
}
message.Content = result ?
message.Content = result.IsSuccess ?
content + " successfully" :
content + " failed";
content + $" failed. {result.ErrorMessage}";
var webDriverService = _services.GetRequiredService<WebDriverService>();
var path = webDriverService.GetScreenshotFilePath(message.MessageId);

View file

@ -25,19 +25,19 @@ public class OpenBrowserFn : IFunctionCallback
url = url.Replace("https://https://", "https://");
var result = await _browser.LaunchBrowser(convService.ConversationId, url);
if (result)
if (result.IsSuccess)
{
message.Content = string.IsNullOrEmpty(url) ? $"Launch browser with blank page successfully." : $"Open website {url} successfully.";
}
else
{
message.Content = "Launch browser failed.";
message.Content = $"Launch browser failed. {result.ErrorMessage}";
}
var path = webDriverService.GetScreenshotFilePath(message.MessageId);
message.Data = await _browser.ScreenshotAsync(convService.ConversationId, path);
return result;
return result.IsSuccess;
}
}

View file

@ -1,45 +0,0 @@
using System.Text.Json.Serialization;
namespace BotSharp.Plugin.WebDriver.LlmContexts;
public class BrowsingContextIn
{
[JsonPropertyName("url")]
public string? Url { get; set; }
[JsonPropertyName("element_name")]
public string? ElementName { get; set; }
[JsonPropertyName("element_type")]
public string? ElementType { get; set; }
[JsonPropertyName("input_text")]
public string? InputText { get; set; }
[JsonPropertyName("element_text")]
public string? ElementText { get; set; }
[JsonPropertyName("attribute_name")]
public string? AttributeName { get; set; }
[JsonPropertyName("attribute_value")]
public string? AttributeValue { get; set; }
[JsonPropertyName("press_enter")]
public bool? PressEnter { get; set; }
[JsonPropertyName("match_rule")]
public string MatchRule { get; set; } = string.Empty;
[JsonPropertyName("update_value")]
public string? UpdateValue { get; set; }
[JsonPropertyName("password")]
public string? Password { get; set; }
[JsonPropertyName("question")]
public string? Question { get; set; }
[JsonPropertyName("direction")]
public string? Direction { get; set; }
}

View file

@ -1,17 +0,0 @@
namespace BotSharp.Plugin.WebDriver.Models;
public class BrowserActionParams
{
public Agent Agent { get; set; }
public BrowsingContextIn Context { get; set; }
public string ConversationId { get; set; }
public string MessageId { get; set; }
public BrowserActionParams(Agent agent, BrowsingContextIn context, string conversationId, string messageId)
{
Agent = agent;
Context = context;
ConversationId = conversationId;
MessageId = messageId;
}
}

View file

@ -1,21 +1,25 @@
global using System;
global using System.Collections.Generic;
global using System.Text;
global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Plugins;
global using System.Threading.Tasks;
global using System.Text.Json;
global using BotSharp.Abstraction.Conversations.Models;
global using System.Linq;
global using System.Text.RegularExpressions;
global using Microsoft.Playwright;
global using Microsoft.Extensions.Configuration;
global using BotSharp.Plugin.WebDriver.Drivers;
global using System.Threading.Tasks;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using BotSharp.Abstraction.Conversations;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Conversations.Models;
global using BotSharp.Abstraction.Functions;
global using BotSharp.Abstraction.Agents.Models;
global using BotSharp.Abstraction.Templating;
global using BotSharp.Plugin.WebDriver.LlmContexts;
global using Microsoft.Extensions.DependencyInjection;
global using System.Linq;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Utilities;
global using BotSharp.Plugin.WebDriver.Models;
global using BotSharp.Plugin.WebDriver.Services;
global using BotSharp.Plugin.WebDriver.Services;
global using BotSharp.Plugin.WebDriver.LlmContexts;
global using BotSharp.Plugin.WebDriver.Drivers;
global using BotSharp.Abstraction.Browsing.Models;
global using BotSharp.Abstraction.Browsing;

View file

@ -224,5 +224,23 @@
},
"required": [ "update_value", "element_text", "match_rule" ]
}
},
{
"name": "send_http_request",
"description": "Send http request to remote server",
"parameters": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "page url start with https://"
},
"payload": {
"type": "string",
"description": "request body"
}
},
"required": [ "url", "payload" ]
}
}
]