Skip to content

improve(browser): batch navigation guard, snapshot delta markers, tool output schema, code-mode recipe#113749

Merged
steipete merged 7 commits into
mainfrom
feat/browser-nav-guard-snapshot-deltas
Jul 25, 2026
Merged

improve(browser): batch navigation guard, snapshot delta markers, tool output schema, code-mode recipe#113749
steipete merged 7 commits into
mainfrom
feat/browser-nav-guard-snapshot-deltas

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

Multi-step browser automation is fragile in three specific ways:

  1. A batch of actions has no awareness of page identity. When an early action triggers a navigation (link click, form submit), the remaining actions run against the new document, where role/name refs resolve to the wrong elements — the batch silently does the wrong thing instead of failing.
  2. Every snapshot is a full re-dump. When something appears in place (autocomplete suggestions, dialogs, validation errors), the model has to mentally diff two large trees to notice, which costs tokens and frequently misses the new elements entirely.
  3. The browser tool declares no output schema, so code-mode catalogs index its output as unknown and agents burn an extra round trip discovering the result shape before they can write filtering code.

Why This Change Was Made

These are the dominant failure modes in longer agent browsing sessions: acting on a stale document, missing in-place UI changes, and dumping full page trees into context. All three are fixable at the tool layer without new input parameters or config surface:

  • Batch navigation guard: batchViaPlaywright now tracks the main-frame URL across actions. A URL-changing navigation (or page close) aborts the remaining actions and returns an aborted summary (reason, afterAction, url, skipped) telling the model to re-snapshot. Snapshot refs are document-scoped; continuing after navigation acts on the wrong document. Same-URL SPA mutations are intentionally out of scope.
  • Snapshot deltas: consecutive compatible snapshots of the same tab and document mark newly appeared ref-bearing elements with [new], report a newElements count, and append a short footer. The baseline is a bounded (32-entry LRU) process-local cache owned by the control-server context; navigation or tab close resets the baseline so a new page is never rendered as a wall of [new] markers.
  • Output schema: the tool now declares a TypeBox output schema covering snapshot, tabs, status, act, and batch-abort result shapes, so code-mode agents can write result-processing code on the first pass.
  • Code-mode recipe: the bundled browser-automation skill gains a concise loop for code-mode sessions — interactive snapshots filtered in code before returning, URL checks between dependent actions, and re-snapshot on aborted/[new].

User Impact

Agents driving the browser through multi-page flows fail less and spend fewer tokens: mid-batch navigations become an explicit, recoverable signal instead of silent wrong-element actions; in-place UI changes (autocomplete, dialogs) are called out directly in the snapshot; code-mode sessions can filter page state in the sandbox instead of round-tripping full trees through model context. No input-schema or config changes; existing callers see purely additive result fields.

Evidence

  • node scripts/run-vitest.mjs extensions/browser: 160 files, 1,980 tests passed (1 skipped), including new coverage for the batch guard (navigation abort, close abort, stopOnError interplay), delta annotation (first-snapshot baseline, same-document markers, navigation reset, truncation interplay), and the output schema.
  • node scripts/check-changed.mjs: formatting, production/test typechecks, lint, boundary guards, import cycles — all green.
  • Live measurement: a 12-challenge deterministic browsing suite (multi-page lookups, autocomplete order flows, new-tab retrieval, 400-row table needle, cross-site price comparison, delayed-render content, in-place reveal chains, multi-page wizard with error recovery), each challenge run twice one-shot against local fixture sites with openai/gpt-5.6-luna on the embedded runtime, isolated per-run sessions, same harness both sides on the same day: baseline (main) 19/24 → this branch 20/24, median wall time 114s → 112s. Aggregate pass rate is statistically flat at this sample size — the wins are in the mechanisms, not the headline: branch transcripts show [new] delta markers firing in 11 events during live autocomplete/reveal flows (baseline: zero, feature absent), directly surfacing in-place DOM changes the model previously had to diff mentally. The batch navigation guard did not trigger in these runs (the model issued no cross-navigation batches); its behavior is locked in by unit tests (navigation abort, same-URL reload via framenavigated, closed-page abort, stopOnError interplay).

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: XL maintainer Maintainer-authored PR labels Jul 25, 2026
@steipete
steipete marked this pull request as ready for review July 25, 2026 15:36
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jul 25, 2026
@clawsweeper

clawsweeper Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 25, 2026, 11:49 AM ET / 15:49 UTC.

ClawSweeper review

What this changes

This PR makes browser batches stop after a main-frame navigation or page close, annotates new elements in compatible consecutive snapshots, declares structured Browser tool outputs, and documents a code-mode browsing loop.

Merge readiness

Blocked until stronger real behavior proof is added - 5 items remain

Keep this PR open for maintainer review. The batch guard addresses a real stale-document hazard, but its current response can report every executed action as successful while silently skipping the remaining requested actions after navigation; that weakens the established batch failure signal for existing programmatic callers.

Priority: P2
Reviewed head: 2b9664a158af0d591feae0c8928a47802ba69acf
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The patch has a focused reliability goal and substantial unit coverage, but its batch completion contract has a P1 compatibility defect and the claimed live proof is not inspectable.
Proof confidence 🦪 silver shellfish (2/6) Needs stronger real behavior proof before merge: The PR body summarizes live fixture-suite results and focused tests, but it does not provide an inspectable after-fix transcript, terminal capture, log, recording, or linked artifact that demonstrates a navigation-aborted batch and successful recovery. Add redacted live evidence; after updating the PR body, a fresh ClawSweeper review should trigger automatically, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦐 gold shrimp (3/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs stronger real behavior proof before merge: The PR body summarizes live fixture-suite results and focused tests, but it does not provide an inspectable after-fix transcript, terminal capture, log, recording, or linked artifact that demonstrates a navigation-aborted batch and successful recovery. Add redacted live evidence; after updating the PR body, a fresh ClawSweeper review should trigger automatically, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 4 items Batch result contract: The existing browser-automation skill describes batch results as ordered success/failure entries and says a failed entry exits nonzero; the proposed batch route instead adds an optional aborted object alongside the successful entries.
Partial-success response path: The changed Playwright action path returns batch results plus aborted metadata, so a consumer checking only the established results array can observe only successful entries even when the guard skipped later requested actions.
Tool-level exposure: The Browser tool formats abort metadata for tool consumers and the new output schema documents the additive shape, but neither changes the prior per-entry success/failure contract for generic batch callers.
Findings 1 actionable finding [P1] Represent an aborted batch as a failure
Security None None.

How this fits together

The bundled Browser plugin turns agent tool calls into browser-control requests and returns snapshots or action results to agents. This PR changes how multi-action batches and repeated snapshots communicate document changes back through that tool boundary.

flowchart LR
  Agent[Agent browser request] --> Tool[Browser tool]
  Tool --> Batch[Batch action executor]
  Tool --> Snapshot[Snapshot route]
  Batch --> Guard[Navigation and close guard]
  Snapshot --> Delta[Per-tab snapshot baseline]
  Guard --> Result[Structured tool result]
  Delta --> Result
  Result --> AgentResponse[Agent recovery or next action]
Loading

Decision needed

Question Recommendation
Should a navigation-aborted browser batch be represented as a normal failed batch result for compatibility, or is the new successful-results-plus-aborted-metadata contract intentionally the permanent API? Preserve failure semantics: Return a failing batch result or tool error when navigation aborts the tail, while keeping aborted metadata for re-snapshot guidance.

Why: The PR intentionally changes whether later requested actions run, but current documented batch consumers are guided by per-entry failures and nonzero failure behavior rather than an aborted field.

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The PR body summarizes live fixture-suite results and focused tests, but it does not provide an inspectable after-fix transcript, terminal capture, log, recording, or linked artifact that demonstrates a navigation-aborted batch and successful recovery. Add redacted live evidence; after updating the PR body, a fresh ClawSweeper review should trigger automatically, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Represent an aborted batch as a failure (P1) - After a navigation or close, this returns only the completed results entries plus optional aborted metadata. Existing callers following the documented batch contract can see an all-successful array and treat the batch as complete even though the guard skipped its tail. Emit a failing entry or an error/nonzero result when the guard aborts, while retaining aborted for recovery details.
  • Resolve merge risk (P1) - Existing clients that treat an all-successful batch results array as completion can continue after the guard has skipped dependent actions; they may not yet know to inspect the new aborted field.
  • Resolve merge risk (P1) - The PR changes the established execution semantics of browser batches without a compatibility-preserving failure result or demonstrated upgrade behavior for non-agent callers.

Findings

  • [P1] Represent an aborted batch as a failure — extensions/browser/src/browser/pw-tools-core.interactions.ts:2007-2010
Agent review details

Security

None.

PR surface

Source +592, Tests +483, Docs +54. Total +1129 across 34 files.

View PR surface stats
Area Files Added Removed Net
Source 22 642 50 +592
Tests 9 501 18 +483
Docs 3 54 0 +54
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 34 1197 68 +1129

Review metrics

Metric Value Why it matters
Batch completion semantics 1 existing batch result contract changed A navigation now stops remaining actions, so callers need an unambiguous failure signal rather than only additive metadata.

Stored data model

Persistent data-model change detected: persistent cache schema: extensions/browser/src/browser/routes/agent.act.ts, persistent cache schema: extensions/browser/src/browser/routes/agent.snapshot.ts, persistent cache schema: extensions/browser/src/browser/routes/tabs.ts, persistent cache schema: extensions/browser/src/browser/snapshot-delta-cache.test.ts, persistent cache schema: extensions/browser/src/browser/snapshot-delta-cache.ts, serialized state: extensions/browser/src/browser/snapshot-delta-cache.ts, and 1 more. Confirm migration or upgrade compatibility proof before merge.

Merge-risk options

Maintainer options:

  1. Return an explicit batch failure on abort (recommended)
    Keep the navigation guard but encode the skipped tail as a failure under the established results/nonzero contract before merge.
  2. Accept and document the contract change
    Maintainers can intentionally adopt aborted metadata as the new completion contract only with explicit migration guidance for programmatic batch callers.
  3. Pause for browser API direction
    Pause this PR if maintainers do not want to change batch completion semantics while existing API consumers remain uncertain.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Make navigation- and close-aborted batches unambiguously fail for existing results-array consumers, retain structured abort metadata, and add focused regression coverage for the tool and HTTP response paths.

Technical review

Best possible solution:

Preserve the guard, but make an aborted batch unambiguously unsuccessful through the established batch result/error contract while retaining structured abort metadata for recovery, then provide a redacted real browser-run artifact that shows the navigation and recovery path.

Do we have a high-confidence way to reproduce the issue?

Yes, source inspection gives a high-confidence path: run a batch whose first action commits a navigation, then observe that the result can contain only successful executed entries plus an aborted summary while later actions are skipped. The PR includes focused unit coverage for navigation and close detection, but no independent runtime execution was possible in this read-only review.

Is this the best way to solve the issue?

Unclear. Stopping after document replacement is the safer behavior, but reporting that partial execution only through a new optional field is not the best compatibility path unless maintainers explicitly adopt that as the Browser batch API.

Full review comments:

  • [P1] Represent an aborted batch as a failure — extensions/browser/src/browser/pw-tools-core.interactions.ts:2007-2010
    After a navigation or close, this returns only the completed results entries plus optional aborted metadata. Existing callers following the documented batch contract can see an all-successful array and treat the batch as complete even though the guard skipped its tail. Emit a failing entry or an error/nonzero result when the guard aborts, while retaining aborted for recovery details.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 924aef2e7c4e.

Labels

Label changes:

  • add P2: This is a bounded browser automation reliability improvement with a concrete compatibility concern, not an established emergency regression.
  • add merge-risk: 🚨 compatibility: The patch changes whether existing multi-action batch callers execute all requested actions and introduces a new completion signal they may not read.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body summarizes live fixture-suite results and focused tests, but it does not provide an inspectable after-fix transcript, terminal capture, log, recording, or linked artifact that demonstrates a navigation-aborted batch and successful recovery. Add redacted live evidence; after updating the PR body, a fresh ClawSweeper review should trigger automatically, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P2: This is a bounded browser automation reliability improvement with a concrete compatibility concern, not an established emergency regression.
  • merge-risk: 🚨 compatibility: The patch changes whether existing multi-action batch callers execute all requested actions and introduces a new completion signal they may not read.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body summarizes live fixture-suite results and focused tests, but it does not provide an inspectable after-fix transcript, terminal capture, log, recording, or linked artifact that demonstrates a navigation-aborted batch and successful recovery. Add redacted live evidence; after updating the PR body, a fresh ClawSweeper review should trigger automatically, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

What I checked:

  • Batch result contract: The existing browser-automation skill describes batch results as ordered success/failure entries and says a failed entry exits nonzero; the proposed batch route instead adds an optional aborted object alongside the successful entries. (extensions/browser/skills/browser-automation/SKILL.md:43, 2b9664a158af)
  • Partial-success response path: The changed Playwright action path returns batch results plus aborted metadata, so a consumer checking only the established results array can observe only successful entries even when the guard skipped later requested actions. (extensions/browser/src/browser/pw-tools-core.interactions.ts:2007, 2b9664a158af)
  • Tool-level exposure: The Browser tool formats abort metadata for tool consumers and the new output schema documents the additive shape, but neither changes the prior per-entry success/failure contract for generic batch callers. (extensions/browser/src/browser/browser-tool.actions.ts:705, 2b9664a158af)
  • Contributor proof statement: The PR body reports focused tests, changed checks, and a live fixture-suite comparison, but no inspectable transcript, terminal capture, or artifact is linked for the claimed after-fix browser runs. (2b9664a158af)

Likely related people:

  • steipete: The supplied history shows seven focused commits in this PR across the Browser tool, browser-control routes, and browser automation documentation; no broader current-main ownership history was available to inspect in the read-only execution environment. (role: recent browser contributor; confidence: low; commits: 94d247b8d74d, 2b9664a158af; files: extensions/browser/src/browser/pw-tools-core.interactions.ts, extensions/browser/src/browser/routes/agent.snapshot.ts)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Return a clear failure/nonzero signal for navigation- or close-aborted batches while retaining abort metadata.
  • Attach a redacted terminal transcript, log, or recording that shows an aborted batch, re-snapshot, and safe follow-up action.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@steipete

Copy link
Copy Markdown
Contributor Author

Addressing the two rank-up moves:

1. Nonzero/failure signal for aborted batches — consciously skipped. The executed prefix of an aborted batch genuinely succeeded (the click worked; it just navigated). Folding that into a failure signal would teach callers that a successful, navigation-causing action is an error, which is exactly the ambiguity the aborted block exists to remove: results[] reports what ran, aborted {reason, afterAction, url, skipped} reports what did not and why. The CLI already exits nonzero when a nested action fails; an abort is a state signal, not a failure.

2. Live transcript — attached below. Managed headless Chromium on an isolated dev gateway against a local fixture site: three-click batch where click 1 navigates; the guard aborts the remaining two with metadata; re-snapshot yields fresh document-scoped refs; follow-up click lands on the target page.

# Batch navigation guard: abort -> re-snapshot -> safe follow-up
# Managed headless Chromium against a local fixture shop (isolated dev gateway).

$ openclaw browser snapshot --interactive        # on /catalog.html
- link "Alpine Anorak" [ref=e1]
- link "Glacier Crampons" [ref=e2]
- link "Summit Stove" [ref=e3]

$ openclaw browser batch --json --actions '[{"kind":"click","ref":"e3"},{"kind":"click","ref":"e1"},{"kind":"click","ref":"e2"}]'
# e3 = "Summit Stove" -> navigates. Pre-guard, the remaining clicks would resolve
# e1/e2 against the NEW document. Now the batch aborts with metadata:
{
  "ok": true,
  "targetId": "E154EA8A11A534577AF0BE679CC107D5",
  "url": "http://127.0.0.1:8931/item-stove.html",
  "results": [
    {
      "ok": true,
      "navigated": true,
      "url": "http://127.0.0.1:8931/item-stove.html"
    }
  ],
  "aborted": {
    "reason": "navigation",
    "afterAction": 1,
    "url": "http://127.0.0.1:8931/item-stove.html",
    "skipped": 2
  }
}

$ openclaw browser snapshot --interactive        # re-snapshot on the new document
- link "Full specifications" [ref=e1]

$ openclaw browser click e1                      # safe follow-up with a fresh ref
clicked ref e1 on http://127.0.0.1:8931/item-stove-specs.html

$ openclaw browser snapshot                      # landed on the specs page
  - heading "Summit Stove — Specifications" [level=1] [ref=e2]
        - cell "Weight" [ref=e6]
        - cell "212 g" [ref=e7]
        - cell "Fuel" [ref=e9]

@steipete
steipete merged commit 4dd8a2b into main Jul 25, 2026
140 of 143 checks passed
@steipete
steipete deleted the feat/browser-nav-guard-snapshot-deltas branch July 25, 2026 17:58
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 26, 2026
…l output schema, code-mode recipe (openclaw#113749)

* feat(browser): guard batches and annotate snapshot deltas

* docs(browser): document reliable automation loops

* test(browser): align batch guard mocks

* fix(browser): reset snapshot deltas after navigation

* fix(browser): detect document navigation without URL equality

* fix(browser): require stable identity for snapshot deltas

* fix(browser): keep snapshot delta helper private
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant