Skip to content

feat(browser): extract action β€” answer page questions via a bounded sub-model call#113861

Merged
steipete merged 4 commits into
mainfrom
feat/browser-extract-action
Jul 25, 2026
Merged

feat(browser): extract action β€” answer page questions via a bounded sub-model call#113861
steipete merged 4 commits into
mainfrom
feat/browser-extract-action

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

Answering a question about a page currently means pulling snapshots into model context β€” often several rounds of snapshot + scroll on long pages β€” which is the slowest and most token-expensive step pattern in browser sessions. The page content transits the main model's context every time, even when the caller only needs one fact.

Why This Change Was Made

Reading is separable from acting. A new extract action answers a question about the current page with one bounded sub-model call and returns only the answer:

  • Capture: Playwright page.content() on the resolved tab (existing-session profiles return the standard Playwright-required 501).
  • Convert: sanitizeHtml β†’ htmlToMarkdown β†’ normalizeWhitespace via openclaw/plugin-sdk/web-content-extractor β€” the same helpers the web-fetch pipeline uses; no new SDK surface.
  • Answer: prepareSimpleCompletionModelForAgent + completeWithPreparedSimpleCompletionModel (openclaw/plugin-sdk/simple-completion-runtime), instructed to answer strictly from page content, reply NOT_FOUND when absent, and treat page text as data (prompt-injection hardening). Input is capped (80k chars, context-window-aware scaling, surrogate-safe truncation) and the whole call runs under a plugin-side deadline (default 60s, clamped 5–120s) with AbortSignal composition β€” an improvement over the vision-describe path, which relies solely on host-side media timeouts.
  • Output: answer wrapped as external untrusted content with [analyzed by <model>] attribution and {url, chars, truncated, model} details; on completion failure the caller is told to fall back to snapshot (no partial dumps).

Wiring follows the existing screenshot-describe precedent exactly: deps injected via browserToolDeps, SDK helpers re-exported through the plugin's sdk-setup-tools.ts barrel. Registered across all surfaces: schema enum + query param + output schema, dispatch, control-server route, node-proxy allowlist, CLI (openclaw browser extract "<question>"), tool description, docs, and the bundled skill.

User Impact

"Read the page and answer X" becomes one tool call, and page content stops flowing through the main model's context β€” the answer comes back as a short wrapped string with model attribution. The wins are context hygiene and main-model token cost in longer sessions, and correctness on pages too large to read comfortably through snapshots; snapshots remain the tool for choosing actions and refs.

Honest scoping from measurement: on a one-shot benchmark (single question per fresh agent, local fixture pages up to 400 KB, gpt-5.6-luna), wall-clock is dominated by session cold-start and shows no significant delta vs. main, and a strong model answers small/medium pages fine from inline page content β€” extract's value materializes in long-lived sessions and skill-guided agents, not toy one-shots. The bundled skill now teaches it and the tool description prefers it for reading tasks.

Evidence

  • Focused tests: 146 passed (handler happy path, NOT_FOUND passthrough, truncation flag, completion failure β†’ fallback error, existing-session 501, missing-query validation; schema contract extended). Full browser shard: 2,040 passed, 1 pre-existing skip; the only failure is the known pre-existing chrome.internal.test.ts baseline failure reproducible on plain origin/main.
  • Typechecks/lint/docs lanes green (Testbox); git diff --check clean.
  • Live verification (isolated dev gateway, managed headless Chromium, openai/gpt-5.6-luna, local 120-section fixture manual): buried-fact query returned exactly Service kit part number: SK-7741-B; torque value: 2.4 Nm; a second buried fact returned 6,800 meters; a question about content not on the page returned NOT_FOUND. Sub-model completions ~450–500 ms each; answers arrived wrapped in the external-content envelope with model attribution. Transcript in the first PR comment.

@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 20:51
@steipete

Copy link
Copy Markdown
Contributor Author

Live verification transcript (isolated dev gateway, managed headless Chromium, openai/gpt-5.6-luna, local 120-section fixture manual):

$ openclaw browser open http://127.0.0.1:8931/manual.html
$ openclaw browser extract "What is the service kit part number for pressure regulator servicing, and what torque value applies?"
[analyzed by openai/gpt-5.6-luna]
Service kit part number: SK-7741-B; torque value: 2.4 Nm.

$ openclaw browser extract "What is the price of the Alpine Anorak?"   # not on this page
NOT_FOUND

$ openclaw browser extract "What is the maximum certified operating altitude?"
6,800 meters.

Sub-model completions were ~450-500 ms each; answers arrived wrapped in the external-untrusted-content envelope with model attribution (envelope elided above for brevity β€” it is the same wrapper the vision-describe path uses).

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: πŸ‘€ ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jul 25, 2026
@clawsweeper

clawsweeper Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 25, 2026, 4:59 PM ET / 20:59 UTC.

ClawSweeper review

What this changes

This PR adds a Browser plugin extract action and CLI command that capture a Playwright-backed page, ask the selected agent model a bounded question about its sanitized readable text, and return only an attributed answer.

Merge readiness

⚠️ Ready for maintainer review - 3 items remain

Keep this PR open for explicit maintainer product-direction review. The proposed Browser plugin feature is additive, uses existing plugin-SDK helpers rather than adding a new SDK API, and the PR includes credible terminal-based live proof; however, it introduces a new model-backed browser and CLI action, so acceptance should be intentional rather than inferred from passing implementation evidence.

Priority: P3
Reviewed head: 5d03fdd2b6fb9f67d07e67f6f242a83f2e7bdfd5
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A well-scoped feature implementation with direct live behavior proof, pending the human decision to support the new public Browser action.
Proof confidence 🐚 platinum hermit (4/6) Sufficient (terminal): The PR includes a post-change terminal transcript from an isolated gateway and managed headless Chromium that shows two correct extracted answers and a NOT_FOUND result; redact any private page data if future proof is posted.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): The PR includes a post-change terminal transcript from an isolated gateway and managed headless Chromium that shows two correct extracted answers and a NOT_FOUND result; redact any private page data if future proof is posted.
Evidence reviewed 5 items Feature implementation: The new extract flow is isolated in the Browser plugin and composes existing page-content, web-content extraction, and simple-completion helpers; it does not add a new core plugin-SDK surface.
Browser-server boundary: The new control-server route clamps its capture timeout, restricts extraction to Playwright-capable profiles, and returns the existing-session fallback message rather than attempting an unsupported Chrome MCP path.
Public contract coverage: The action is registered in the browser tool schema and output schema, with explicit query, character-count, truncation, and model fields.
Findings None None.
Security None None.

How this fits together

The Browser plugin gives agents and operators control over managed Chromium pages through tool calls, CLI commands, and the browser control server. This change adds a read-only path from the selected page’s HTML through existing content-extraction and simple-completion helpers to a short, externally wrapped answer.

flowchart LR
  A[Agent or CLI question] --> B[Browser extract action]
  B --> C[Playwright-managed page]
  C --> D[Sanitized readable page text]
  D --> E[Bounded selected-model completion]
  E --> F[External-content wrapped answer]
  B --> G[Snapshot fallback on failure]
Loading

Decision needed

Question Recommendation
Should OpenClaw expose a first-class browser extract action that answers page questions with a bounded model call instead of requiring snapshot text in the primary agent context? Sponsor the extract action: Accept the bounded model-backed read path as a supported Browser plugin capability, subject to the normal final CI and owner review.

Why: The implementation is additive and tested, but it creates a new public tool and CLI behavior with an intentional model-call and page-content-processing product contract.

Before merge

  • Resolve merge risk (P1) - This is a new public Browser tool and CLI capability that invokes a model over readable page content; maintainers should explicitly confirm that the context-cost, latency, and operator-facing behavior are desired before merging.
  • Complete next step (P2) - A maintainer needs to sponsor or decline the new public Browser and CLI action; there is no narrow mechanical repair to dispatch.
Agent review details

Security

None.

PR surface

Source +545, Tests +444, Docs +30. Total +1019 across 32 files.

View PR surface stats
Area Files Added Removed Net
Source 22 549 4 +545
Tests 5 445 1 +444
Docs 5 36 6 +30
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 32 1030 11 +1019

Review metrics

None.

Stored data model

Persistent data-model change detected: serialized state: extensions/browser/src/browser/client-actions-observe.ts. Confirm migration or upgrade compatibility proof before merge.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Adopt extract as the Browser plugin’s documented read-only page-question path if maintainers want a bounded model call alongside snapshots, while keeping snapshots as the canonical action-ref and page-structure workflow.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Adopt extract as the Browser plugin’s documented read-only page-question path if maintainers want a bounded model call alongside snapshots, while keeping snapshots as the canonical action-ref and page-structure workflow.

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

Not applicable as a bug reproduction: this PR adds a new capability. The PR does provide a concrete after-fix runtime transcript covering successful extraction and the NOT_FOUND path on a managed browser profile.

Is this the best way to solve the issue?

Unclear until product direction is confirmed. The implementation follows the existing Browser plugin and plugin-SDK seams and keeps snapshots available, but maintainers must decide whether this new public model-backed reading mode belongs in the supported Browser contract.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 9faaa789017b.

Labels

Label changes:

  • add P3: This is a new, optional Browser plugin capability rather than an urgent regression or established-behavior repair.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR includes a post-change terminal transcript from an isolated gateway and managed headless Chromium that shows two correct extracted answers and a NOT_FOUND result; redact any private page data if future proof is posted.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: πŸ‘€ ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR includes a post-change terminal transcript from an isolated gateway and managed headless Chromium that shows two correct extracted answers and a NOT_FOUND result; redact any private page data if future proof is posted.

Label justifications:

  • P3: This is a new, optional Browser plugin capability rather than an urgent regression or established-behavior repair.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: πŸ‘€ ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR includes a post-change terminal transcript from an isolated gateway and managed headless Chromium that shows two correct extracted answers and a NOT_FOUND result; redact any private page data if future proof is posted.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR includes a post-change terminal transcript from an isolated gateway and managed headless Chromium that shows two correct extracted answers and a NOT_FOUND result; redact any private page data if future proof is posted.

Evidence

What I checked:

  • Feature implementation: The new extract flow is isolated in the Browser plugin and composes existing page-content, web-content extraction, and simple-completion helpers; it does not add a new core plugin-SDK surface. (extensions/browser/src/browser-extract.ts:1, 5d03fdd2b6fb)
  • Browser-server boundary: The new control-server route clamps its capture timeout, restricts extraction to Playwright-capable profiles, and returns the existing-session fallback message rather than attempting an unsupported Chrome MCP path. (extensions/browser/src/browser/routes/agent.extract.ts:22, 5d03fdd2b6fb)
  • Public contract coverage: The action is registered in the browser tool schema and output schema, with explicit query, character-count, truncation, and model fields. (extensions/browser/src/browser-tool.schema.ts:43, 5d03fdd2b6fb)
  • Live behavior proof: The PR discussion includes a post-change terminal transcript from an isolated gateway and managed headless Chromium: two buried facts were returned and an absent fact returned NOT_FOUND. The transcript is direct runtime proof, although it uses a local fixture page. (5d03fdd2b6fb)
  • Repository boundary policy: The PR keeps production Browser-plugin imports behind the plugin-local sdk-setup-tools barrel, consistent with the repository rule that plugins cross into core through documented plugin-SDK surfaces. (AGENTS.md, 9faaa789017b)

Likely related people:

  • steipete: The PR’s four commits implement the extract action across the Browser plugin, its routes, CLI, tests, skill, and documentation; no separate current-main ownership trail was available in the read-only review environment. (role: feature proposer and Browser-plugin contributor; confidence: medium; commits: 709e4ab3047d, 9cd49a8ad3d1, 8d6fc1200d7b; files: extensions/browser/src/browser-extract.ts, extensions/browser/src/browser-tool.ts, extensions/browser/src/browser/routes/agent.extract.ts)

Rank-up moves

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

  • Obtain explicit maintainer sponsorship for the new Browser and CLI surface.
  • Let the remaining required CI checks complete for the current head.

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

Rank-up move dispositions:

  1. Maintainer sponsorship β€” sponsored: this Browser/CLI surface was built at the repo owner's explicit direction (browser speed/efficiency track; same sponsorship as improve(browser): batch navigation guard, snapshot delta markers, tool output schema, code-mode recipeΒ #113749, which landed the batch navigation guard and snapshot deltas).
  2. Required CI checks β€” complete: all checks green on head 5d03fdd (the earlier check-dependencies failure was an over-exported pair of module-local types, fixed in that head).

@steipete
steipete merged commit 4cdd9b8 into main Jul 25, 2026
139 of 143 checks passed
@steipete
steipete deleted the feat/browser-extract-action branch July 25, 2026 22:13
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

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 P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XL status: πŸ‘€ ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant