mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 09:35:59 -04:00
agent: derive Action enum from tool_defs and clean up Verifier
- Derives the `Action` enum in `src/browser/tools.zig` from `tool_defs` to prevent manual maintenance and potential drift. - Refactors `verifyElementValue` in `src/script/Verifier.zig` to use a `Check` struct for its parameters. - Reorganizes and cleans up imports in `src/agent/Agent.zig`.
This commit is contained in:
@@ -4,15 +4,16 @@ const lp = @import("lightpanda");
|
||||
|
||||
const log = lp.log;
|
||||
const Config = lp.Config;
|
||||
const App = @import("../App.zig");
|
||||
const ToolExecutor = @import("ToolExecutor.zig");
|
||||
const Terminal = @import("Terminal.zig");
|
||||
const script = lp.script;
|
||||
const Command = lp.script.Command;
|
||||
const Recorder = lp.script.Recorder;
|
||||
const Verifier = lp.script.Verifier;
|
||||
|
||||
const App = @import("../App.zig");
|
||||
const ToolExecutor = @import("ToolExecutor.zig");
|
||||
const Terminal = @import("Terminal.zig");
|
||||
const CommandExecutor = @import("CommandExecutor.zig");
|
||||
const SlashCommand = @import("SlashCommand.zig");
|
||||
const script = lp.script;
|
||||
|
||||
const Agent = @This();
|
||||
|
||||
|
||||
@@ -369,30 +369,17 @@ const ActionTarget = union(enum) {
|
||||
|
||||
const NodeAndPage = struct { node: *DOMNode, page: *lp.Frame, target: ActionTarget };
|
||||
|
||||
pub const Action = enum {
|
||||
goto,
|
||||
search,
|
||||
markdown,
|
||||
links,
|
||||
nodeDetails,
|
||||
interactiveElements,
|
||||
structuredData,
|
||||
detectForms,
|
||||
eval,
|
||||
tree,
|
||||
click,
|
||||
fill,
|
||||
scroll,
|
||||
waitForSelector,
|
||||
hover,
|
||||
press,
|
||||
selectOption,
|
||||
setChecked,
|
||||
findElement,
|
||||
getEnv,
|
||||
consoleLogs,
|
||||
getUrl,
|
||||
getCookies,
|
||||
/// Derived from `tool_defs` so the enum and the tool table can't drift.
|
||||
/// Tag order follows declaration order in `tool_defs`.
|
||||
pub const Action = blk: {
|
||||
var fields: [tool_defs.len]std.builtin.Type.EnumField = undefined;
|
||||
for (tool_defs, 0..) |td, i| fields[i] = .{ .name = td.name[0..td.name.len :0], .value = i };
|
||||
break :blk @Type(.{ .@"enum" = .{
|
||||
.tag_type = u8,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.is_exhaustive = true,
|
||||
} });
|
||||
};
|
||||
|
||||
pub fn call(
|
||||
|
||||
@@ -46,24 +46,30 @@ fn verifyFill(self: *Self, arena: std.mem.Allocator, selector: []const u8, expec
|
||||
};
|
||||
return .{ .result = .passed };
|
||||
}
|
||||
return self.verifyElementValue(arena, selector, "value", expected_value, "value");
|
||||
return self.verifyElementValue(arena, selector, .{ .js_property = "value", .expected = expected_value, .label = "value" });
|
||||
}
|
||||
|
||||
fn verifyCheck(self: *Self, arena: std.mem.Allocator, selector: []const u8, expected: bool) VerifyResult {
|
||||
const expected_str: []const u8 = if (expected) "true" else "false";
|
||||
return self.verifyElementValue(arena, selector, "String(el.checked)", expected_str, "checked state");
|
||||
return self.verifyElementValue(arena, selector, .{ .js_property = "String(el.checked)", .expected = expected_str, .label = "checked state" });
|
||||
}
|
||||
|
||||
fn verifySelect(self: *Self, arena: std.mem.Allocator, selector: []const u8, expected_value: []const u8) VerifyResult {
|
||||
return self.verifyElementValue(arena, selector, "value", expected_value, "selected value");
|
||||
return self.verifyElementValue(arena, selector, .{ .js_property = "value", .expected = expected_value, .label = "selected value" });
|
||||
}
|
||||
|
||||
fn verifyElementValue(self: *Self, arena: std.mem.Allocator, selector: []const u8, js_property: []const u8, expected: []const u8, label: []const u8) VerifyResult {
|
||||
const actual = self.queryElementProperty(arena, selector, js_property) orelse return .{ .result = .inconclusive };
|
||||
if (!std.mem.eql(u8, actual, expected))
|
||||
const Check = struct {
|
||||
js_property: []const u8,
|
||||
expected: []const u8,
|
||||
label: []const u8,
|
||||
};
|
||||
|
||||
fn verifyElementValue(self: *Self, arena: std.mem.Allocator, selector: []const u8, check: Check) VerifyResult {
|
||||
const actual = self.queryElementProperty(arena, selector, check.js_property) orelse return .{ .result = .inconclusive };
|
||||
if (!std.mem.eql(u8, actual, check.expected))
|
||||
return .{
|
||||
.result = .failed,
|
||||
.reason = std.fmt.allocPrint(arena, "element {s} is \"{s}\" (expected \"{s}\")", .{ label, actual, expected }) catch null,
|
||||
.reason = std.fmt.allocPrint(arena, "element {s} is \"{s}\" (expected \"{s}\")", .{ check.label, actual, check.expected }) catch null,
|
||||
};
|
||||
return .{ .result = .passed };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user