Skip to content

feat(adapters): WebVoyager task loader via the answer-submit interception path - #356

Open
vaibhavdabas16 wants to merge 5 commits into
TIGER-AI-Lab:mainfrom
vaibhavdabas16:feat/webvoyager-adapter
Open

feat(adapters): WebVoyager task loader via the answer-submit interception path#356
vaibhavdabas16 wants to merge 5 commits into
TIGER-AI-Lab:mainfrom
vaibhavdabas16:feat/webvoyager-adapter

Conversation

@vaibhavdabas16

Copy link
Copy Markdown
Contributor

Advances #190 (and #72, step 4). Stacked on #345 — the adapter foundation — so the diff shows both until that merges; the WebVoyager-specific commits are 43f5c76 and a06083b.

What this is

A task loader for MinorJerry/WebVoyager: reads data/WebVoyager_data.jsonl and data/reference_answer.json from a checkout and produces ClawBenchTasks.

clawbench-sources cases webvoyager:/path/to/WebVoyager
clawbench-sources show webvoyager    # status + field-mapping table

The design decision worth reviewing

WebVoyager scores by a screenshot-and-LLM judge over the trajectory. There is no final write request for Stage 1 to intercept, which is the one thing ClawBench's scoring keys on. The easy answer was to mark these tasks llm_judge_only with no eval_schema and leave them unrunnable until a runner change.

But ClawBench already solved exactly this shape for the claw-eval port, and it's in main: the instruction tells the agent to submit its final answer at the runtime server's http://127.0.0.1:7878/submit form, that form POSTs to /api/task-submit, the task's eval_schema targets that endpoint, and the LLM judge scores the submitted answer against judge_context. The adapter reuses that path verbatim — same endpoint, same footer wording — so a WebVoyager task runs through the ordinary Stage-1 + Stage-2 pipeline with zero runner changes and produces the standard trace bundle. A test pins the contract against a real bundled claw-eval task so the two can't drift.

Mapping

ClawBench WebVoyager
task_id / source_id id (lower-cased / verbatim)
instruction ques + submit footer
url web
category web_name
time_limit 10 min — upstream is step-bounded (15 steps), not wall-clock; matches the claw-eval port
judge_context.reference_solution reference_answer.json entries, labelled [golden] / [possible] so the judge can weigh them

Missing start URL or missing reference → AdapterWarning on the task, never a silent drop. No id or no quesAdapterError with the line number. The reference-file parser skips anything that doesn't match the upstream shape rather than guessing at it.

Testing

tests/test_webvoyager_adapter.py — 15 cases against a synthetic fixture in the upstream file shape (deliberately not upstream content): field mapping, the interception contract matching claw-eval, labelled references, both missing-reference cases (no entry vs. no file), missing URL, direct .jsonl path, four malformed-checkout failures with locations, to_task_json() validated against task.schema.json, and the CLI. Full suite: 317 passed, 10 skipped; ruff and pyright clean.

Not done here, and said so in the doc

eval/adapters/webvoyager.md is the walkthrough #190 asks for. It's explicit that the upstream screenshot-judge passthrough — both scores side by side in run-meta.json, which is the comparison #190 is really after — is not attempted: that needs their judge prompt wired as a second scorer plus a runner change to record a second verdict. This loader is the prerequisite for it. The ±3pp reproduction check follows from that, and pinned_sha waits on the shared _pins.yaml (#72 step 5).

I have not run this against a real WebVoyager checkout — the field names (web_name / id / ques / web) match #72's mapping table and my understanding of the upstream file, but a maintainer with a clone should run clawbench-sources cases webvoyager:<clone> once before merge.

First step of the incremental plan in TIGER-AI-Lab#72: the shared target type, the
registry, and an identity adapter, with no behaviour change for bundled
tasks.

`ClawBenchTask` is a superset of test-cases/task.schema.json plus the
provenance an imported task needs — which source it came from and that
source's own id — so a leaderboard can partition rows by origin. Time
limits stay in minutes, matching task.json and the container watchdog,
because most upstream schemas use seconds and the conversion has to live
somewhere explicit.

Adapters declare which scoring layers they can honour. A layer a source
cannot support is meant to score null rather than 0, so aggregation never
confuses "the agent failed" with "never scored on that axis";
to_task_json() therefore refuses to render a task with no interception
contract instead of inventing one.

Fields with no 1:1 mapping surface as an AdapterWarning naming the field,
the fallback, and the pinned upstream revision the mapping was written
against — a task is never dropped silently.

Validation is hand-rolled rather than Pydantic: the package has no
Pydantic dependency and its other registries (harness_registry) validate
frozen dataclasses exactly this way.
`clawbench-sources` lists the registered adapters with their upstream,
pin, declared scoring layers, and whether a checkout is present; `show`
prints one source's status and its module field-mapping table; `cases`
lists the tasks a source exposes, with any load warnings.

TIGER-AI-Lab#72 sketches this as `clawbench sources`, but `clawbench` is the TUI and
every non-interactive command in this repo is its own `clawbench-<verb>`
entrypoint, so it follows that convention instead.

A source is addressable as `<name>:<path>` to pin it to an explicit
clone; otherwise it resolves under CLAWBENCH_SOURCES_DIR, XDG_CACHE_HOME,
or ~/.cache. CLAWBENCH_OFFLINE is honoured up front so a later fetching
adapter fails loudly instead of cloning.
Adds docs/task-sources.md covering the CLI, the shared task type, the
scoring-layer contract, field-mapping warnings, and how to write an
adapter, plus the CHANGELOG entry and a docs/cli.md row.

Tests cover the registry, source-spec parsing and cache resolution, the
schema's validation and task.json rendering, the native loader against
both a suite directory and a corpus root, and each CLI subcommand.
WebVoyager scores by a screenshot-and-LLM judge over the trajectory; there
is no final write request for Stage 1 to intercept. ClawBench already
solved that shape for the claw-eval port: the instruction tells the agent
to submit its final answer at the runtime server's /submit form, POST
/api/task-submit is the interception target, and the LLM judge scores the
submitted answer against the reference. This adapter reuses that path
exactly, so a WebVoyager task runs through the standard two-stage
pipeline with no runner change.

Maps id/ques/web/web_name from data/WebVoyager_data.jsonl and attaches
the matching data/reference_answer.json entries — labelled [golden] or
[possible] so the judge can weigh them — as judge_context. A missing
start URL or reference becomes a warning on the task, never a silent
drop; a task with no id or question fails the load with its line number.
eval/adapters/webvoyager.md covers getting the tasks, how a WebVoyager
task scores under ClawBench, the field mapping, and what is deliberately
not done here (the upstream screenshot-judge passthrough, the reproduction
check, pinning). The test fixture is a synthetic sample in the upstream
file shape, not upstream content.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant