command: check required fields for null-arg tool calls

Tool calls with null arguments are now only considered recorded if the
tool schema has no required fields. This prevents generating invalid,
unreplayable commands for tools like `goto` or `fill`.
This commit is contained in:
Adrià Arrufat
2026-05-22 09:09:19 +02:00
parent a3eeec0b26
commit df42d18d6d

View File

@@ -56,9 +56,9 @@ pub const Command = union(enum) {
.tool_call => |tc| blk: {
const s = schemaOf(tc);
if (!s.recorded) break :blk false;
const args = tc.args orelse break :blk s.required.len == 0;
// backendNodeId is invalidated by any DOM mutation, so calls
// using it aren't replayable.
const args = tc.args orelse break :blk true;
if (args == .object and args.object.contains("backendNodeId")) break :blk false;
break :blk true;
},
@@ -500,6 +500,17 @@ test "isRecorded / canHeal / producesData via tool flags" {
try testing.expect(!login.canHeal());
}
test "isRecorded: null args on a required-fields tool are not recorded" {
// A provider that hands back `arguments: null` for `/click` would
// otherwise produce a bare `/click` line that can't be replayed.
const click_null = Command.fromToolCall(.click, null);
try testing.expect(click_null.isRecorded()); // click has zero required fields
const goto_null = Command.fromToolCall(.goto, null);
try testing.expect(!goto_null.isRecorded()); // goto requires url
const fill_null = Command.fromToolCall(.fill, null);
try testing.expect(!fill_null.isRecorded()); // fill requires value
}
test "ScriptIterator: basic slash commands" {
const content =
"/goto https://example.com\n" ++