diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
index 2ad912dc0..fadeacd1b 100644
--- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
+++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
@@ -50,8 +50,9 @@
-
-
+
+
+
@@ -70,10 +71,13 @@
PreserveNewest
-
+
PreserveNewest
-
+
+ PreserveNewest
+
+
PreserveNewest
diff --git a/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs
index 206c22d59..0e965bada 100644
--- a/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs
+++ b/src/Infrastructure/BotSharp.Core/Planning/HFPlanner.cs
@@ -91,7 +91,7 @@ public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, Ro
private string GetNextStepPrompt(Agent router)
{
- var template = router.Templates.First(x => x.Name == "next_step_prompt.hf_planner").Content;
+ var template = router.Templates.First(x => x.Name == "planner_prompt.hf").Content;
var render = _services.GetRequiredService();
var prompt = render.Render(template, router.TemplateDict);
return prompt.Trim();
diff --git a/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs
index 6db3a40ab..d7e334513 100644
--- a/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs
+++ b/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs
@@ -108,7 +108,7 @@ public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, Ro
private string GetNextStepPrompt(Agent router)
{
- var template = router.Templates.First(x => x.Name == "next_step_prompt").Content;
+ var template = router.Templates.First(x => x.Name == "planner_prompt.naive").Content;
var render = _services.GetRequiredService();
return render.Render(template, new Dictionary
diff --git a/src/Infrastructure/BotSharp.Core/Planning/SequentialPlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/SequentialPlanner.cs
new file mode 100644
index 000000000..fd85863cd
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core/Planning/SequentialPlanner.cs
@@ -0,0 +1,112 @@
+using BotSharp.Abstraction.Agents.Models;
+using BotSharp.Abstraction.Functions.Models;
+using BotSharp.Abstraction.Planning;
+using BotSharp.Abstraction.Routing;
+using BotSharp.Abstraction.Routing.Models;
+using BotSharp.Abstraction.Templating;
+
+namespace BotSharp.Core.Planning;
+
+public class SequentialPlanner : IPlaner
+{
+ private readonly IServiceProvider _services;
+ private readonly ILogger _logger;
+
+ public SequentialPlanner(IServiceProvider services, ILogger logger)
+ {
+ _services = services;
+ _logger = logger;
+ }
+
+ public async Task GetNextInstruction(Agent router, string messageId)
+ {
+ var next = GetNextStepPrompt(router);
+
+ var inst = new FunctionCallFromLlm();
+
+ // text completion
+ /*var agentService = _services.GetRequiredService();
+ var instruction = agentService.RenderedInstruction(router);
+ var content = $"{instruction}\r\n###\r\n{next}";
+ content = content + "\r\nResponse: ";
+ var completion = CompletionProvider.GetTextCompletion(_services);*/
+
+ // chat completion
+ var completion = CompletionProvider.GetChatCompletion(_services,
+ provider: router?.LlmConfig?.Provider,
+ model: router?.LlmConfig?.Model);
+
+ int retryCount = 0;
+ while (retryCount < 3)
+ {
+ string text = string.Empty;
+ try
+ {
+ // text completion
+ // text = await completion.GetCompletion(content, router.Id, messageId);
+ var dialogs = new List
+ {
+ new RoleDialogModel(AgentRole.User, next)
+ {
+ MessageId = messageId
+ }
+ };
+ var response = await completion.GetChatCompletions(router, dialogs);
+
+ inst = response.Content.JsonContent();
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"{ex.Message}: {text}");
+ inst.Function = "response_to_user";
+ inst.Response = ex.Message;
+ inst.AgentName = "Router";
+ }
+ finally
+ {
+ retryCount++;
+ }
+ }
+
+ return inst;
+ }
+
+ public async Task AgentExecuting(Agent router, FunctionCallFromLlm inst, RoleDialogModel message)
+ {
+ // Set user content as Planner's question
+ message.FunctionName = inst.Function;
+ message.FunctionArgs = inst.Arguments == null ? "{}" : JsonSerializer.Serialize(inst.Arguments);
+
+ return true;
+ }
+
+ public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, RoleDialogModel message)
+ {
+ var context = _services.GetRequiredService();
+
+ if (message.StopCompletion)
+ {
+ context.Empty();
+ return false;
+ }
+
+ // Handover to Router;
+ context.Pop();
+
+ var routing = _services.GetRequiredService();
+ routing.ResetRecursiveCounter();
+
+ return true;
+ }
+
+ private string GetNextStepPrompt(Agent router)
+ {
+ var template = router.Templates.First(x => x.Name == "planner_prompt.sequential").Content;
+
+ var render = _services.GetRequiredService();
+ return render.Render(template, new Dictionary
+ {
+ });
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs
index 7b4dc3183..c0881ed2f 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs
@@ -37,12 +37,16 @@ public void RegisterDI(IServiceCollection services, IConfiguration config)
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
+
services.AddScoped(provider =>
{
var settingService = provider.GetRequiredService();
var routingSettings = settingService.Bind("Router");
if (routingSettings.Planner == nameof(HFPlanner))
return provider.GetRequiredService();
+ else if (routingSettings.Planner == nameof(SequentialPlanner))
+ return provider.GetRequiredService();
else
return provider.GetRequiredService();
});
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.hf_planner.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.hf.liquid
similarity index 100%
rename from src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.hf_planner.liquid
rename to src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.hf.liquid
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.naive.liquid
similarity index 100%
rename from src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/next_step_prompt.liquid
rename to src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.naive.liquid
diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.sequential.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.sequential.liquid
new file mode 100644
index 000000000..33f8db9f6
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/templates/planner_prompt.sequential.liquid
@@ -0,0 +1,3 @@
+In order to execute the instructions listed by the user in the order specified by the user.
+What is the next step based on the CONVERSATION?
+Response must be in required JSON format.
\ No newline at end of file
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.Selenium.csproj b/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.Selenium.csproj
deleted file mode 100644
index 20ca51750..000000000
--- a/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.Selenium.csproj
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- netstandard2.1
- enable
- $(MSBuildProjectName.Replace(" ", "_"))s
-
-
-
-
-
-
-
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj b/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj
index d78a7e12b..205f32bf7 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs
index 2c08a0ad6..f3a453adb 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.ChangeListValue.cs
@@ -1,4 +1,5 @@
using BotSharp.Plugin.WebDriver.Services;
+using System.Threading;
namespace BotSharp.Plugin.WebDriver.Drivers.PlaywrightDriver;
@@ -10,22 +11,49 @@ public async Task ChangeListValue(Agent agent, BrowsingContextIn context, string
var body = await _instance.Page.QuerySelectorAsync("body");
var str = new List();
- var inputs = await body.QuerySelectorAllAsync("input");
+ var inputs = await body.QuerySelectorAllAsync("select");
foreach (var input in inputs)
{
- var text = await input.TextContentAsync();
+ var html = "";
+ str.Add(html);
}
var driverService = _services.GetRequiredService();
@@ -36,10 +64,41 @@ public async Task ChangeListValue(Agent agent, BrowsingContextIn context, string
throw new Exception($"Can't locate the web element {context.ElementName}.");
}
- var element = _instance.Page.Locator(htmlElementContextOut.TagName).Nth(htmlElementContextOut.Index);
+ ILocator element = default;
+ if (!string.IsNullOrEmpty(htmlElementContextOut.ElementId))
+ {
+ // await _instance.Page.WaitForSelectorAsync($"#{htmlElementContextOut.ElementId}", new PageWaitForSelectorOptions { Timeout = 3 });
+ element = _instance.Page.Locator($"#{htmlElementContextOut.ElementId}");
+ }
+ else
+ {
+ element = _instance.Page.Locator(htmlElementContextOut.TagName).Nth(htmlElementContextOut.Index);
+ }
+
try
{
- await element.FillAsync(context.InputText);
+ var isVisible = await element.IsVisibleAsync();
+
+ if (!isVisible)
+ {
+ // Select the element you want to make visible (replace with your own selector)
+ var control = await _instance.Page.QuerySelectorAsync($"#{htmlElementContextOut.ElementId}");
+
+ // Show the element by modifying its CSS styles
+ await _instance.Page.EvaluateAsync(@"(element) => {
+ element.style.display = 'block';
+ element.style.visibility = 'visible';
+ }", control);
+ }
+
+ await element.FocusAsync();
+ await element.SelectOptionAsync(new SelectOptionValue
+ {
+ Label = context.UpdateValue
+ });
+
+ // Click on the blank area to activate posting
+ await body.ClickAsync();
}
catch (Exception ex)
{
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs
index a325a076f..abfc300f3 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs
@@ -4,6 +4,7 @@ public partial class PlaywrightWebDriver
{
private readonly IServiceProvider _services;
private readonly PlaywrightInstance _instance;
+ public PlaywrightInstance Instance => _instance;
public PlaywrightWebDriver(IServiceProvider services, PlaywrightInstance instance)
{
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs
index 4431e1e3e..1002351b9 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ChangeListValueFn.cs
@@ -23,9 +23,10 @@ public async Task Execute(RoleDialogModel message)
var agentService = _services.GetRequiredService();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
+ await _driver.Instance.Page.WaitForLoadStateAsync(LoadState.Load);
await _driver.ChangeListValue(agent, args, message.MessageId);
- message.Content = "Update successfully.";
+ message.Content = $"Updat the value of \"${args.ElementName}\" to \"{args.UpdateValue}\" successfully.";
return true;
}
}
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs
index bb4b81f9a..afa8da5d0 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ClickButtonFn.cs
@@ -23,9 +23,10 @@ public async Task Execute(RoleDialogModel message)
var agentService = _services.GetRequiredService();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
+ await _driver.Instance.Page.WaitForLoadStateAsync(LoadState.Load);
await _driver.ClickElement(agent, args, message.MessageId);
- message.Content = "Executed successfully.";
+ message.Content = $"Click button {args.ElementName} successfully.";
return true;
}
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs
index 82692bfbc..71c3fa397 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/ExtractDataFn.cs
@@ -23,6 +23,7 @@ public async Task Execute(RoleDialogModel message)
var args = JsonSerializer.Deserialize(message.FunctionArgs);
var agentService = _services.GetRequiredService();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
+ await _driver.Instance.Page.WaitForLoadStateAsync(LoadState.Load);
message.Content = await _driver.ExtractData(agent, args, message.MessageId);
return true;
}
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs
index 30aae3327..ccafd7212 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserPasswordFn.cs
@@ -23,6 +23,7 @@ public async Task Execute(RoleDialogModel message)
var agentService = _services.GetRequiredService();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
+ await _driver.Instance.Page.WaitForLoadStateAsync(LoadState.Load);
await _driver.InputUserPassword(agent, args, message.MessageId);
message.Content = "Input password successfully";
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs
index 246c6011d..b5052965d 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/InputUserTextFn.cs
@@ -23,9 +23,10 @@ public async Task Execute(RoleDialogModel message)
var agentService = _services.GetRequiredService();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
+ await _driver.Instance.Page.WaitForLoadStateAsync(LoadState.Load);
await _driver.InputUserText(agent, args, message.MessageId);
- message.Content = "Input text successfully.";
+ message.Content = $"Input text \"{args.InputText}\" successfully.";
return true;
}
}
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs
index 94e18cae6..8a7323da6 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/Functions/OpenBrowserFn.cs
@@ -20,9 +20,7 @@ public async Task Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize(message.FunctionArgs);
var browser = await _driver.LaunchBrowser(args.Url);
- message.Content = string.IsNullOrEmpty(args.Url) ? "Launch browser successfully." : $"Open website successfully.";
- message.Content += "\r\nWhat would you like to do next?";
- message.StopCompletion = true;
+ message.Content = string.IsNullOrEmpty(args.Url) ? $"Launch browser with blank page successfully." : $"Open website {args.Url} successfully.";
return true;
}
}
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/LlmContexts/HtmlElementContextOut.cs b/src/Plugins/BotSharp.Plugin.WebDriver/LlmContexts/HtmlElementContextOut.cs
index a325a4f6c..a0fbfaf6a 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/LlmContexts/HtmlElementContextOut.cs
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/LlmContexts/HtmlElementContextOut.cs
@@ -4,6 +4,9 @@ namespace BotSharp.Plugin.WebDriver.LlmContexts;
public class HtmlElementContextOut
{
+ [JsonPropertyName("element_id")]
+ public string ElementId { get; set; }
+
[JsonPropertyName("tag_name")]
public string TagName { get; set; }
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/agent.json b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/agent.json
index d2250da1a..5a12078d7 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/agent.json
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/agent.json
@@ -1,9 +1,9 @@
{
- "name": "Web Driver",
- "description": "Perform a specific action on a web browser",
- "createdDateTime": "2024-01-02T00:00:00Z",
- "updatedDateTime": "2024-01-02T00:00:00Z",
- "id": "f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b",
- "allowRouting": true,
- "isPublic": true
- }
\ No newline at end of file
+ "name": "Web Driver",
+ "description": "Perform a specific action on a web browser",
+ "createdDateTime": "2024-01-02T00:00:00Z",
+ "updatedDateTime": "2024-01-02T00:00:00Z",
+ "id": "f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b",
+ "allowRouting": true,
+ "isPublic": true
+}
\ No newline at end of file
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/functions.json b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/functions.json
index 78128f017..49e4770bc 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/functions.json
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/functions.json
@@ -7,7 +7,7 @@
"properties": {
"url": {
"type": "string",
- "description": "website url."
+ "description": "website url starts with https://"
}
},
"required": ["url"]
@@ -67,7 +67,7 @@
"properties": {
"element_name": {
"type": "string",
- "description": "the html input box element name."
+ "description": "the html selection element name."
},
"update_value": {
"type": "string",
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/instruction.liquid b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/instruction.liquid
index 4f6d65dd3..c41ef2355 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/instruction.liquid
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/instruction.liquid
@@ -3,6 +3,8 @@ You are a Web Driver that can manipulate web elements through automation tools.
Follow below steps to response:
1. Analyze user's latest request in the conversation.
2. Call appropriate function to execute the instruction.
+3. If user requests execute multiple steps, execute them sequentially.
Additional response requirements:
-* Call function input_user_password if user wants to input password.
\ No newline at end of file
+* Call function input_user_password if user wants to input password.
+* Don't do extra steps if user didn't ask.
\ No newline at end of file
diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/templates/html_parser.liquid b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/templates/html_parser.liquid
index 2e9c8bf50..c19918610 100644
--- a/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/templates/html_parser.liquid
+++ b/src/Plugins/BotSharp.Plugin.WebDriver/data/agents/f3ae2a0f-e6ba-4ee1-a0b9-75d7431ff32b/templates/html_parser.liquid
@@ -1,5 +1,6 @@
{{ html_content }}
=== According to above HTML ===
-Find the html element tag name of "{{ element_name }}".
-Output in JSON format {"tag_name": "", "index": -1} with appropriate values, the "index" starts with 0.
\ No newline at end of file
+Find the html element in the similar meaning of "{{ element_name }}".
+Output in JSON format {"tag_name": "", "element_id": "populated if element has id", "index": -1} with appropriate values.
+The index is the position of the element which starts with 0.
\ No newline at end of file