Octopus
Fill Form Tool
The browser_fill and browser_click tools allow agents to interact with web forms — typing into inputs, selecting dropdowns, and clicking buttons to submit.
browser_fill Schema
{
"name": "browser_fill",
"description": "Fill an input field, textarea, or select element with a value. " +
"Clears existing content before typing.",
"inputSchema": {
"type": "object",
"properties": {
"selector": {
"type": "string",
"description": "CSS selector for the input element"
},
"value": {
"type": "string",
"description": "The value to type into the field"
},
"clear_first": {
"type": "boolean",
"default": true,
"description": "Clear existing content before filling"
},
"delay_ms": {
"type": "integer",
"default": 0,
"description": "Delay in ms between keystrokes (0 = instant, use 50-100 to simulate human typing)"
}
},
"required": ["selector", "value"]
}
}
browser_click Schema
{
"name": "browser_click",
"description": "Click an element on the page. Use for buttons, links, checkboxes, and radio buttons.",
"inputSchema": {
"type": "object",
"properties": {
"selector": {
"type": "string",
"description": "CSS selector of the element to click"
},
"button": {
"type": "string",
"enum": ["left", "right", "middle"],
"default": "left",
"description": "Mouse button to click with"
},
"wait_for_navigation": {
"type": "boolean",
"default": false,
"description": "If true, waits for navigation to complete after clicking (for submit buttons)"
}
},
"required": ["selector"]
}
}
Complete Form Interaction Example
// Agent tool call sequence for submitting a search form:
// 1. Navigate to the search page
browser_navigate: { "url": "https://portal.company.com/search" }
// 2. Fill the search input
browser_fill: { "selector": "#search-input", "value": "quarterly report 2024" }
// 3. Click the search button (wait for results to load)
browser_click: {
"selector": "button[type='submit']",
"wait_for_navigation": true
}
// 4. Extract the search results
browser_extract: { "selector": ".search-result-title", "format": "json", "limit": 5 }
Handler Implementation
public async Task<string> HandleFillAsync(
JsonElement input, IBrowserSession session, CancellationToken ct)
{
var selector = input.GetProperty("selector").GetString()!;
var value = input.GetProperty("value").GetString()!;
var clearFirst = !input.TryGetProperty("clear_first", out var c) || c.GetBoolean();
var delayMs = input.TryGetProperty("delay_ms", out var d) ? d.GetInt32() : 0;
var page = await session.GetPageAsync(ct);
var element = await page.WaitForSelectorAsync(selector, new() { Timeout = _config.TimeoutMs });
if (element is null)
return JsonSerializer.Serialize(new { error = $"Selector '{selector}' not found." });
if (clearFirst)
await element.FillAsync(value); // Playwright's Fill clears first automatically
else
await element.TypeAsync(value, new() { Delay = delayMs });
return JsonSerializer.Serialize(new
{
filled = true,
selector,
value = value.Length > 50 ? value[..50] + "..." : value
});
}
public async Task<string> HandleClickAsync(
JsonElement input, IBrowserSession session, CancellationToken ct)
{
var selector = input.GetProperty("selector").GetString()!;
var button = input.TryGetProperty("button", out var b) ? b.GetString()! : "left";
var waitForNavigation = input.TryGetProperty("wait_for_navigation", out var w) && w.GetBoolean();
var page = await session.GetPageAsync(ct);
if (waitForNavigation)
{
await Task.WhenAll(
page.WaitForNavigationAsync(new() { Timeout = _config.NavigationTimeoutMs }),
page.ClickAsync(selector, new() { Button = ParseButton(button) })
);
}
else
{
await page.ClickAsync(selector, new() { Button = ParseButton(button) });
}
return JsonSerializer.Serialize(new { clicked = true, selector, current_url = page.Url });
}
Confirm before submitting forms. Agents should always confirm form values with the user before calling
browser_click on submit buttons. Form submissions are often irreversible (order placement, data deletion, etc.).