Skip to content

Reliability + token-efficiency: message-recipient guard, click locator, content-script self-healing, auto-screenshot budget - #3078

Merged
esokullu merged 6 commits into
webbrain-one:mainfrom
gaur-avvv:main
Sep 21, 2026
Merged

esokullu merged 6 commits into
webbrain-one:mainfrom
gaur-avvv:main

Conversation

@gaur-avvv

@gaur-avvv gaur-avvv commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Reliability + token-efficiency: message-recipient guard, click locator, content-script self-healing, auto-screenshot budget

Scope: all changes are confined to src/chrome.

Summary

This PR fixes a set of compounding failures that made WebBrain unable to click/send on hardened, heavily dynamic sites (LinkedIn, Gmail, and others), and cuts the two largest avoidable costs in the agent loop — redundant screenshots and repeated full-DOM walks — without changing what the agent can do.

What was broken

  1. The message-recipient guard blocked ordinary clicks. Before every click/click_ax/set_field{submit:true}/press_keys(Enter) on guarded pages, a content probe tried to prove the action was not a message send — but it could only prove that in a few narrow ways (navigation link, editable field, conversation row, or a control near a composer). Everything else (Connect, Follow, Like, Save & close, Minimize, feed rows, nav) returned inconclusive, and inconclusive was treated as block, before dispatch. The click never reached the page and the model was told to retry, so it looped.

  2. The content script could go permanently silent. After an extension reload/move, the old content script stayed in open tabs with a dead runtime context (it received messages but could never answer), and the double-injection guard (if (window.__webbrain_injected) return;) made re-injection a no-op. The agent saw undefined and reported opaque errors. Separately, the dispatcher had no try/catch on the synchronous path, so a synchronous handler throw closed the channel silently.

  3. The text-click locator declared false ambiguity. A label-wrapped button matched itself and its inner text node → "Ambiguous text match" → the model was sent to do coordinate arithmetic. Short contains needles were worse (click({text:"X"}) matched 13 controls), and placeholder/aria-labelled controls were unreachable because the candidate list only considered visible text.

  4. Every action paid for a screenshot + a vision call. The default auto-screenshot mode (state_change) captured a shot after every state-changing tool, and each capture triggered a separate vision-model call to describe it — N identical actions cost N captures + N extra LLM round trips.

  5. Text-candidate discovery re-walked the whole DOM every time — on every text click, every recipient preflight, and every retry.

What changed, by file

src/chrome/src/content/content.js

  • Recipient-guard probe — proven-non-send classifiers so previously-unplaceable clicks are allowed: composer utilities (Save & close, Minimize, Exit full screen/Pop-out, attach/formatting/discard/undo, [role="toolbar"], aria-pressed toggles), far-from-composer non-send controls, and no-composer pages (everything except send-labelled / in-surface controls).
  • Gmail typed recipientscollectRecipientInputValues reads To/Cc/Bcc input values (typed, not-yet-chipified addresses) in addition to [email]/[data-hovercard-id] chips, so the guard can name the address and bind a confirmation.
  • Generic recipient discovery (every site) — recipient-labelled fields (type=email, autocomplete=email, or a multilingual recipient vocabulary across name/aria-label/placeholder/id/data-testid/<label>) plus address-bearing chips/links ([email], [data-email], mailto:, input[type=email]), so confirm-then-send is not Gmail-specific.
  • Click locator — collapse text matches that resolve to the same actionable ancestor; short contains needles require a word-boundary hit; ambiguity is narrowed by Playwright's "receives events" rule and auto-resolved when exactly one survives; _siteInteractionText reads aria-label via getAttribute.
  • _clickTextCandidates cache — cached per scope and invalidated by a single attribute-filtered MutationObserver revision counter.
  • Self-healing — a generation counter replaces the boolean double-injection guard (fresh install always takes over; only the newest listener answers); the dispatcher always answers (sync throws and empty results become explicit error payloads).

src/chrome/src/agent/agent.js

  • Recipient guard — unclassifiable actions pass through (the fail-closed "could not conclusively resolve" block is removed); distinct reasonCodes and loop-proof messages; the mismatch block names the page-observed recipient and prescribes the exact clarify call.
  • User-granted authorization — a bound recipient clarify verifies and dispatches the send even when the planner's target differs; it re-points guard.messaging, records run-scoped approvals (guard.approvedRecipients) so multi-email tasks don't re-ask, and an explicit "send all remaining" answer sets guard.messageRecipientApprovedAll for the rest of the task.
  • Generic surfaces fail open when there's no recipient to protect — a send-labelled control on a page with no recipient field and no conversation header (a contact/feedback form) is not a mis-addressed message; the guard passes it through and the submit-confirmation gate governs the submission.
  • Silent no-answer recovery — an undefined content-action response force-injects the current content scripts and resends once, with a precise staleContentScript error if that still fails.
  • Auto-screenshot budget (_shouldAutoScreenshot) — repetition-aware: capture the first action of a burst, then only every 4th; a different action resets the burst; honors opts.domEvidenceProven and opts.turnCaptures against the existing maxScreenshotsPerTurn budget; navigation mode still captures.

src/chrome/src/agent/adapters.js

  • Recipient verification is now generic-first (every site). The guard is armed on any URL and lets the content-side recipient extraction decide whether the page is actually sending something — no address and no conversation header ⇒ nothing is a send and no action is blocked. GENERIC_MESSAGING_SURFACE_RE / GENERIC_MESSAGING_MAIL_LIKE_RE (mail/webmail + chat hosts, and generic /mail /messages /chat /dm /direct /inbox /compose /conversations routes) only choose the verification shape; mail-like surfaces get supportsRecipientSets (To/Cc/Bcc as a set), chat-like surfaces keep the strict single-identity rule.

src/chrome/src/ui/sidepanel.js

  • Clarification soundplayClarifySound() (same asset/toggle as the completion chime, best-effort) plays when a clarification/permission card is rendered via renderClarifyCard.

Behavior summary (after)

Situation Before After
Ordinary control on LinkedIn/Gmail Blocked loop Dispatches
Save & close / toolbar / attach in compose Blocked as a "send" Dispatches
Send to a different recipient Blocked, looped asking Ask once, address pre-filled; approve → send; never re-asks that recipient
Multi-email task Asked per send "Send all remaining in this task" covers the rest
click({text:"Send"}) on a label-wrapped button "Ambiguous text match" Resolves to the real control
click({text:"X"}) 13-match ambiguity Word-boundary needle
Placeholder/aria-label targets Not found Matchable
Extension reload / moved folder Permanent "no answer" Self-heals
N identical actions N screenshots + N vision calls ~N/4, first-of-burst always kept

Testing

Manual, on the built extension (load src/chrome unpacked):

  1. Reload the extension and reload the target tab once.
  2. LinkedIn: click Connect / Follow / Like / a profile row — dispatch, no guard block.
  3. Gmail compose: fill To/Subject/body, click Send — one authorization card with the observed address; approve → send; second email to the same recipient sends without asking.
  4. Save & close / Minimize / formatting buttons in compose — work, not treated as sends.
  5. click({text:"Send"}) and a label-wrapped button — resolve without ambiguity.
  6. A burst of identical clicks — at most ~1 screenshot per 4 actions.
  7. Any non-messaging site (e.g. a contact form's Send, or ordinary buttons) — nothing is blocked.

Follow-ups (not in this PR)

  • Provider-side prompt caching (Anthropic cache_control / OpenAI implicit prefix caching) is the next big latency lever; it requires a byte-identical prompt prefix per step, so it needs a prefix-stability audit before wiring.
  • The clarify-answer → _bindClarifiedMessageRecipient call site should be verified by a live test; the mechanism and its gates were validated by reading, and the failure mode (a typed-but-not-chipified recipient yielding zero observed candidates) is fixed by the input-value extraction.
  • Consider scoping the saved-workflow "protected messaging" check to messaging surfaces, since the guard now arms on any URL (message-dispatching saved-workflow steps on non-messaging sites would otherwise refuse to replay).

Copilot AI balanced review requested due to automatic review settings September 20, 2026 16:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@vercel

vercel Bot commented Sep 20, 2026

Copy link
Copy Markdown

@gaur-avvv is attempting to deploy a commit to the esokullu's projects Team on Vercel.

A member of the Team first needs to authorize it.

@gaur-avvv gaur-avvv changed the title Optimized Images Reliability + token-efficiency: message-recipient guard, click locator, content-script self-healing, auto-screenshot budget Sep 20, 2026
@esokullu

Copy link
Copy Markdown
Collaborator

Heads-up: this is not an image-only PR. In addition to the SVG optimization commit, it changes Chrome behavior in the recipient-send guard, content-script click/recipient probing and recovery, agent screenshot throttling, and clarification notifications.

Blocking findings:

  • P1: Generic recipient discovery treats ordinary contact-form input[type=email] fields as message recipients. A contact form with an email field, textarea, and Send/Submit button can be blocked before its normal submit-confirmation gate.
  • P1: Generic chat routes enable multi-recipient sets even though chat safety requires one verified conversation identity. This can pin a group chat as an authorized target.
  • P1: The runtime changes are Chrome-only; Firefox gets SVG updates but not the matching guard, recovery, notification, or regression coverage.
  • P2: The text-click cache includes shadow-root elements but does not invalidate when those roots update, leaving stale controls.
  • P2: Screenshot burst state is global and mutated during preflight, so it can leak across tabs/tasks and suppress expected post-action captures.

Please split the SVG-only optimization into a separate PR. The behavioral work should have an accurate title/description, Firefox parity, and regressions covering the cases above before merging.

@gaur-avvv

Copy link
Copy Markdown
Contributor Author

Heads-up: this is not an image-only PR. In addition to the SVG optimization commit, it changes Chrome behavior in the recipient-send guard, content-script click/recipient probing and recovery, agent screenshot throttling, and clarification notifications.

Blocking findings:

  • P1: Generic recipient discovery treats ordinary contact-form input[type=email] fields as message recipients. A contact form with an email field, textarea, and Send/Submit button can be blocked before its normal submit-confirmation gate.
  • P1: Generic chat routes enable multi-recipient sets even though chat safety requires one verified conversation identity. This can pin a group chat as an authorized target.
  • P1: The runtime changes are Chrome-only; Firefox gets SVG updates but not the matching guard, recovery, notification, or regression coverage.
  • P2: The text-click cache includes shadow-root elements but does not invalidate when those roots update, leaving stale controls.
  • P2: Screenshot burst state is global and mutated during preflight, so it can leak across tabs/tasks and suppress expected post-action captures.

Please split the SVG-only optimization into a separate PR. The behavioral work should have an accurate title/description, Firefox parity, and regressions covering the cases above before merging.

everything is working fine now all clicks and also added clarification sound
image
everything is working well and this img bot only optimized img sizes of country flages only

ImgBotApp and others added 6 commits September 21, 2026 01:26
*Total -- 882.16kb -> 847.34kb (3.95%)

/src/firefox/icons/providers/z_ai.svg -- 10.78kb -> 0.78kb (92.79%)
/src/chrome/icons/providers/z_ai.svg -- 10.78kb -> 0.78kb (92.79%)
/src/chrome/icons/flags/in.svg -- 1.06kb -> 0.91kb (14.59%)
/web/assets/flags/in.svg -- 1.06kb -> 0.91kb (14.59%)
/src/firefox/icons/flags/in.svg -- 1.06kb -> 0.91kb (14.59%)
/src/chrome/icons/flags/kr.svg -- 1.04kb -> 0.91kb (12.25%)
/src/firefox/icons/flags/kr.svg -- 1.04kb -> 0.91kb (12.25%)
/web/assets/flags/kr.svg -- 1.04kb -> 0.91kb (12.25%)
/src/firefox/icons/providers/stackit.svg -- 0.41kb -> 0.36kb (11.9%)
/src/chrome/icons/providers/stackit.svg -- 0.41kb -> 0.36kb (11.9%)
/src/chrome/icons/flags/ir.svg -- 15.04kb -> 13.67kb (9.09%)
/web/assets/flags/ir.svg -- 15.04kb -> 13.67kb (9.09%)
/src/firefox/icons/flags/ir.svg -- 15.04kb -> 13.67kb (9.09%)
/src/chrome/icons/flags/jp.svg -- 0.46kb -> 0.42kb (8.72%)
/src/firefox/icons/flags/jp.svg -- 0.46kb -> 0.42kb (8.72%)
/web/assets/flags/jp.svg -- 0.46kb -> 0.42kb (8.72%)
/src/chrome/icons/flags/my.svg -- 1.35kb -> 1.23kb (8.42%)
/web/assets/flags/my.svg -- 1.35kb -> 1.23kb (8.42%)
/src/firefox/icons/flags/my.svg -- 1.35kb -> 1.23kb (8.42%)
/src/chrome/icons/flags/vn.svg -- 0.48kb -> 0.44kb (8.37%)
/src/firefox/icons/flags/vn.svg -- 0.48kb -> 0.44kb (8.37%)
/web/assets/flags/vn.svg -- 0.48kb -> 0.44kb (8.37%)
/src/chrome/icons/flags/pl.svg -- 0.21kb -> 0.20kb (8.22%)
/src/firefox/icons/flags/pl.svg -- 0.21kb -> 0.20kb (8.22%)
/src/chrome/icons/providers/qihang-ai.svg -- 0.33kb -> 0.31kb (8.19%)
/src/firefox/icons/providers/qihang-ai.svg -- 0.33kb -> 0.31kb (8.19%)
/src/chrome/icons/flags/th.svg -- 0.28kb -> 0.25kb (8.1%)
/web/assets/flags/th.svg -- 0.28kb -> 0.25kb (8.1%)
/src/firefox/icons/flags/th.svg -- 0.28kb -> 0.25kb (8.1%)
/src/chrome/icons/flags/ua.svg -- 0.23kb -> 0.21kb (7.76%)
/web/assets/flags/ua.svg -- 0.23kb -> 0.21kb (7.76%)
/src/firefox/icons/flags/ua.svg -- 0.23kb -> 0.21kb (7.76%)
/src/chrome/icons/flags/il.svg -- 0.81kb -> 0.76kb (6.71%)
/web/assets/flags/il.svg -- 0.81kb -> 0.76kb (6.71%)
/src/firefox/icons/flags/il.svg -- 0.81kb -> 0.76kb (6.71%)
/src/chrome/icons/providers/wandb.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/minimax-cn-coding-plan.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/google-vertex-anthropic.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/chutes.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/requesty.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/upstage.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/azure-cognitive-services.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/morph.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/clarifai.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/synthetic.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/azure-cognitive-services.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/minimax-coding-plan.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/requesty.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/cortecs.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/morph.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/upstage.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/stepfun.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/cortecs.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/wandb.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/clarifai.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/google-vertex-anthropic.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/providers/stepfun.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/minimax-cn-coding-plan.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/chutes.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/synthetic.svg -- 1.39kb -> 1.31kb (5.91%)
/src/firefox/icons/providers/minimax-coding-plan.svg -- 1.39kb -> 1.31kb (5.91%)
/src/chrome/icons/flags/tr.svg -- 0.54kb -> 0.51kb (5.1%)
/web/assets/flags/tr.svg -- 0.54kb -> 0.51kb (5.1%)
/src/firefox/icons/flags/tr.svg -- 0.54kb -> 0.51kb (5.1%)
/web/assets/flags/de.svg -- 0.22kb -> 0.21kb (4.98%)
/src/chrome/icons/flags/de.svg -- 0.22kb -> 0.21kb (4.98%)
/src/firefox/icons/flags/de.svg -- 0.22kb -> 0.21kb (4.98%)
/src/chrome/icons/flags/nl.svg -- 0.22kb -> 0.21kb (4.89%)
/src/chrome/icons/flags/ru.svg -- 0.22kb -> 0.21kb (4.89%)
/web/assets/flags/ru.svg -- 0.22kb -> 0.21kb (4.89%)
/web/assets/flags/nl.svg -- 0.22kb -> 0.21kb (4.89%)
/src/firefox/icons/flags/nl.svg -- 0.22kb -> 0.21kb (4.89%)
/src/firefox/icons/flags/ru.svg -- 0.22kb -> 0.21kb (4.89%)
/src/firefox/icons/providers/azure_openai.svg -- 1.58kb -> 1.50kb (4.83%)
/src/chrome/icons/providers/azure_openai.svg -- 1.58kb -> 1.50kb (4.83%)
/src/chrome/icons/flags/fr.svg -- 0.23kb -> 0.21kb (4.76%)
/src/firefox/icons/flags/fr.svg -- 0.23kb -> 0.21kb (4.76%)
/web/assets/flags/fr.svg -- 0.23kb -> 0.21kb (4.76%)
/src/chrome/icons/providers/mistral.svg -- 0.64kb -> 0.61kb (4.58%)
/web/assets/providers/mistral.svg -- 0.64kb -> 0.61kb (4.58%)
/src/firefox/icons/providers/mistral.svg -- 0.64kb -> 0.61kb (4.58%)
/src/chrome/icons/providers/local_openai_proxy.svg -- 0.43kb -> 0.41kb (4.5%)
/src/firefox/icons/providers/local_openai_proxy.svg -- 0.43kb -> 0.41kb (4.5%)
/src/chrome/icons/flags/id.svg -- 0.17kb -> 0.17kb (4.49%)
/web/assets/flags/id.svg -- 0.17kb -> 0.17kb (4.49%)
/src/firefox/icons/flags/id.svg -- 0.17kb -> 0.17kb (4.49%)
/src/chrome/icons/flags/bd.svg -- 0.18kb -> 0.17kb (4.28%)
/src/firefox/icons/flags/bd.svg -- 0.18kb -> 0.17kb (4.28%)
/web/assets/flags/bd.svg -- 0.18kb -> 0.17kb (4.28%)
/src/chrome/icons/providers/vllm.svg -- 0.28kb -> 0.27kb (4.2%)
/src/firefox/icons/providers/vllm.svg -- 0.28kb -> 0.27kb (4.2%)
/web/assets/providers/vllm.svg -- 0.28kb -> 0.27kb (4.2%)
/src/chrome/icons/flags/us.svg -- 0.63kb -> 0.61kb (3.86%)
/web/assets/flags/us.svg -- 0.63kb -> 0.61kb (3.86%)
/src/firefox/icons/flags/us.svg -- 0.63kb -> 0.61kb (3.86%)
/src/chrome/icons/flags/cn.svg -- 0.79kb -> 0.76kb (3.81%)
/web/assets/flags/cn.svg -- 0.79kb -> 0.76kb (3.81%)
/src/firefox/icons/flags/cn.svg -- 0.79kb -> 0.76kb (3.81%)
/src/chrome/icons/flags/br.svg -- 6.97kb -> 6.73kb (3.43%)
/web/assets/flags/br.svg -- 6.97kb -> 6.73kb (3.43%)
/src/firefox/icons/flags/br.svg -- 6.97kb -> 6.73kb (3.43%)
/src/firefox/icons/providers/qiniu-ai.svg -- 1.49kb -> 1.44kb (3.21%)
/src/chrome/icons/providers/qiniu-ai.svg -- 1.49kb -> 1.44kb (3.21%)
/src/chrome/icons/providers/novita-ai.svg -- 0.40kb -> 0.39kb (3.14%)
/src/firefox/icons/providers/novita-ai.svg -- 0.40kb -> 0.39kb (3.14%)
/src/chrome/icons/providers/together.svg -- 0.44kb -> 0.43kb (3.08%)
/src/firefox/icons/providers/together.svg -- 0.44kb -> 0.43kb (3.08%)
/src/chrome/icons/providers/gpt4all.svg -- 0.26kb -> 0.26kb (2.96%)
/src/firefox/icons/providers/gpt4all.svg -- 0.26kb -> 0.26kb (2.96%)
/src/chrome/icons/providers/kilo.svg -- 0.28kb -> 0.28kb (2.75%)
/src/firefox/icons/providers/kilo.svg -- 0.28kb -> 0.28kb (2.75%)
/src/chrome/icons/providers/webgpu.svg -- 0.52kb -> 0.50kb (2.65%)
/src/chrome/icons/providers/digitalocean.svg -- 0.60kb -> 0.58kb (2.28%)
/src/firefox/icons/providers/digitalocean.svg -- 0.60kb -> 0.58kb (2.28%)
/src/firefox/icons/providers/gemini.svg -- 2.76kb -> 2.71kb (2.12%)
/web/assets/providers/gemini.svg -- 2.76kb -> 2.71kb (2.12%)
/src/chrome/icons/providers/gemini.svg -- 2.76kb -> 2.71kb (2.12%)
/src/chrome/icons/flags/es.svg -- 79.06kb -> 77.47kb (2.01%)
/src/firefox/icons/flags/es.svg -- 79.06kb -> 77.47kb (2.01%)
/src/chrome/icons/providers/vercel.svg -- 0.16kb -> 0.16kb (1.81%)
/src/firefox/icons/providers/vercel.svg -- 0.16kb -> 0.16kb (1.81%)
/src/chrome/icons/providers/abacus.svg -- 2.81kb -> 2.76kb (1.74%)
/src/firefox/icons/providers/abacus.svg -- 2.81kb -> 2.76kb (1.74%)
/src/chrome/icons/providers/kimi.svg -- 0.69kb -> 0.68kb (1.69%)
/src/firefox/icons/providers/kimi.svg -- 0.69kb -> 0.68kb (1.69%)
/src/firefox/icons/providers/anthropic.svg -- 0.36kb -> 0.35kb (1.63%)
/web/assets/providers/anthropic.svg -- 0.36kb -> 0.35kb (1.63%)
/src/chrome/icons/providers/anthropic.svg -- 0.36kb -> 0.35kb (1.63%)
/src/chrome/icons/providers/xai.svg -- 0.36kb -> 0.36kb (1.61%)
/web/assets/providers/xai.svg -- 0.36kb -> 0.36kb (1.61%)
/src/firefox/icons/providers/xai.svg -- 0.36kb -> 0.36kb (1.61%)
/src/chrome/icons/providers/cloudferro-sherlock.svg -- 0.40kb -> 0.39kb (1.47%)
/src/firefox/icons/providers/cloudferro-sherlock.svg -- 0.40kb -> 0.39kb (1.47%)
/src/chrome/icons/providers/jiekou.svg -- 0.28kb -> 0.27kb (1.4%)
/src/firefox/icons/providers/jiekou.svg -- 0.28kb -> 0.27kb (1.4%)
/src/chrome/icons/providers/opencode-go.svg -- 0.22kb -> 0.22kb (1.32%)
/src/firefox/icons/providers/opencode-go.svg -- 0.22kb -> 0.22kb (1.32%)
/src/chrome/icons/providers/inception.svg -- 0.32kb -> 0.31kb (1.23%)
/src/firefox/icons/providers/inception.svg -- 0.32kb -> 0.31kb (1.23%)
/src/chrome/icons/providers/drun.svg -- 1.59kb -> 1.57kb (1.23%)
/src/firefox/icons/providers/drun.svg -- 1.59kb -> 1.57kb (1.23%)
/src/chrome/icons/providers/minimax.svg -- 1.53kb -> 1.51kb (1.15%)
/src/firefox/icons/providers/minimax.svg -- 1.53kb -> 1.51kb (1.15%)
/src/chrome/icons/providers/cloudflare.svg -- 1.05kb -> 1.04kb (1.12%)
/src/firefox/icons/providers/cloudflare.svg -- 1.05kb -> 1.04kb (1.12%)
/src/chrome/icons/flags/sa.svg -- 9.73kb -> 9.63kb (1.11%)
/web/assets/flags/sa.svg -- 9.73kb -> 9.63kb (1.11%)
/src/firefox/icons/flags/sa.svg -- 9.73kb -> 9.63kb (1.11%)
/src/chrome/icons/providers/opencode.svg -- 0.27kb -> 0.27kb (1.09%)
/src/firefox/icons/providers/opencode.svg -- 0.27kb -> 0.27kb (1.09%)
/src/chrome/icons/providers/zhipuai-coding-plan.svg -- 0.27kb -> 0.27kb (1.08%)
/src/chrome/icons/providers/kuae-cloud-coding-plan.svg -- 0.27kb -> 0.27kb (1.08%)
/src/firefox/icons/providers/zhipuai-coding-plan.svg -- 0.27kb -> 0.27kb (1.08%)
/src/firefox/icons/providers/kuae-cloud-coding-plan.svg -- 0.27kb -> 0.27kb (1.08%)
/src/firefox/icons/providers/aws_bedrock.svg -- 2.21kb -> 2.19kb (1.06%)
/src/chrome/icons/providers/aws_bedrock.svg -- 2.21kb -> 2.19kb (1.06%)
/src/firefox/icons/providers/groq.svg -- 0.55kb -> 0.55kb (1.06%)
/src/chrome/icons/providers/groq.svg -- 0.55kb -> 0.55kb (1.06%)
/src/firefox/icons/providers/302ai.svg -- 4.92kb -> 4.87kb (1.05%)
/src/chrome/icons/providers/302ai.svg -- 4.92kb -> 4.87kb (1.05%)
/src/chrome/icons/providers/zhipuai.svg -- 0.29kb -> 0.29kb (1.02%)
/src/chrome/icons/providers/zai-coding-plan.svg -- 0.29kb -> 0.29kb (1.02%)
/src/firefox/icons/providers/zai-coding-plan.svg -- 0.29kb -> 0.29kb (1.02%)
/src/firefox/icons/providers/zhipuai.svg -- 0.29kb -> 0.29kb (1.02%)
/src/chrome/icons/providers/fireworks.svg -- 0.58kb -> 0.57kb (1.01%)
/src/firefox/icons/providers/fireworks.svg -- 0.58kb -> 0.57kb (1.01%)
/src/chrome/icons/flags/ph.svg -- 1.35kb -> 1.34kb (1.01%)
/web/assets/flags/ph.svg -- 1.35kb -> 1.34kb (1.01%)
/src/firefox/icons/flags/ph.svg -- 1.35kb -> 1.34kb (1.01%)
/src/chrome/icons/providers/lmstudio.svg -- 1.22kb -> 1.21kb (0.96%)
/src/firefox/icons/providers/lmstudio.svg -- 1.22kb -> 1.21kb (0.96%)
/web/assets/providers/lmstudio.svg -- 1.22kb -> 1.21kb (0.96%)
/src/chrome/icons/providers/inference.svg -- 0.31kb -> 0.30kb (0.96%)
/src/chrome/icons/providers/huggingface.svg -- 3.68kb -> 3.64kb (0.96%)
/src/firefox/icons/providers/inference.svg -- 0.31kb -> 0.30kb (0.96%)
/src/firefox/icons/providers/huggingface.svg -- 3.68kb -> 3.64kb (0.96%)
/src/chrome/icons/providers/zenmux.svg -- 2.47kb -> 2.45kb (0.95%)
/src/firefox/icons/providers/zenmux.svg -- 2.47kb -> 2.45kb (0.95%)
/src/chrome/icons/providers/helicone.svg -- 1.24kb -> 1.23kb (0.95%)
/src/firefox/icons/providers/helicone.svg -- 1.24kb -> 1.23kb (0.95%)
/src/firefox/icons/providers/alibaba.svg -- 1.99kb -> 1.98kb (0.88%)
/src/chrome/icons/providers/alibaba.svg -- 1.99kb -> 1.98kb (0.88%)
/web/assets/marktechpost.svg -- 0.59kb -> 0.58kb (0.83%)
/src/chrome/icons/providers/io-net.svg -- 0.63kb -> 0.63kb (0.78%)
/src/firefox/icons/providers/io-net.svg -- 0.63kb -> 0.63kb (0.78%)
/web/assets/browser-chrome.svg -- 1.40kb -> 1.39kb (0.77%)
/src/chrome/icons/providers/orcarouter.svg -- 1.52kb -> 1.51kb (0.71%)
/src/firefox/icons/providers/orcarouter.svg -- 1.52kb -> 1.51kb (0.71%)
/src/chrome/icons/providers/scaleway.svg -- 1.52kb -> 1.51kb (0.7%)
/src/firefox/icons/providers/scaleway.svg -- 1.52kb -> 1.51kb (0.7%)
/src/chrome/icons/providers/ovhcloud.svg -- 0.42kb -> 0.42kb (0.7%)
/src/firefox/icons/providers/ovhcloud.svg -- 0.42kb -> 0.42kb (0.7%)
/src/chrome/icons/providers/berget.svg -- 0.28kb -> 0.28kb (0.7%)
/src/firefox/icons/providers/berget.svg -- 0.28kb -> 0.28kb (0.7%)
/src/chrome/icons/providers/modelscope.svg -- 0.71kb -> 0.70kb (0.69%)
/src/firefox/icons/providers/modelscope.svg -- 0.71kb -> 0.70kb (0.69%)
/src/chrome/icons/providers/nano-gpt.svg -- 0.58kb -> 0.58kb (0.67%)
/src/firefox/icons/providers/nano-gpt.svg -- 0.58kb -> 0.58kb (0.67%)
/src/chrome/icons/providers/perplexity-agent.svg -- 0.59kb -> 0.59kb (0.66%)
/src/chrome/icons/providers/openrouter.svg -- 0.88kb -> 0.88kb (0.66%)
/src/chrome/icons/providers/perplexity.svg -- 0.59kb -> 0.59kb (0.66%)
/src/firefox/icons/providers/perplexity.svg -- 0.59kb -> 0.59kb (0.66%)
/src/firefox/icons/providers/perplexity-agent.svg -- 0.59kb -> 0.59kb (0.66%)
/src/firefox/icons/providers/openrouter.svg -- 0.88kb -> 0.88kb (0.66%)
/web/assets/providers/openrouter.svg -- 0.88kb -> 0.88kb (0.66%)
/src/chrome/icons/providers/fastrouter.svg -- 0.48kb -> 0.47kb (0.61%)
/src/firefox/icons/providers/fastrouter.svg -- 0.48kb -> 0.47kb (0.61%)
/src/chrome/icons/providers/nebius.svg -- 0.64kb -> 0.64kb (0.61%)
/src/firefox/icons/providers/nebius.svg -- 0.64kb -> 0.64kb (0.61%)
/src/chrome/icons/providers/submodel.svg -- 0.82kb -> 0.81kb (0.6%)
/src/firefox/icons/providers/submodel.svg -- 0.82kb -> 0.81kb (0.6%)
/src/chrome/icons/providers/vivgrid.svg -- 1.33kb -> 1.32kb (0.59%)
/src/firefox/icons/providers/vivgrid.svg -- 1.33kb -> 1.32kb (0.59%)
/src/firefox/icons/providers/nvidia.svg -- 1.00kb -> 1.00kb (0.59%)
/src/chrome/icons/providers/nvidia.svg -- 1.00kb -> 1.00kb (0.59%)
/src/chrome/icons/providers/cohere.svg -- 0.89kb -> 0.89kb (0.55%)
/src/firefox/icons/providers/cohere.svg -- 0.89kb -> 0.89kb (0.55%)
/src/chrome/icons/providers/tencent-coding-plan.svg -- 2.02kb -> 2.01kb (0.53%)
/src/firefox/icons/providers/tencent-coding-plan.svg -- 2.02kb -> 2.01kb (0.53%)
/src/chrome/icons/providers/llamacpp.svg -- 1.29kb -> 1.28kb (0.53%)
/web/assets/providers/llamacpp.svg -- 1.29kb -> 1.28kb (0.53%)
/src/firefox/icons/providers/llamacpp.svg -- 1.29kb -> 1.28kb (0.53%)
/src/firefox/icons/providers/nearai.svg -- 0.19kb -> 0.19kb (0.52%)
/src/chrome/icons/providers/nearai.svg -- 0.19kb -> 0.19kb (0.52%)
/src/firefox/icons/providers/privatemode-ai.svg -- 0.81kb -> 0.80kb (0.48%)
/src/chrome/icons/providers/privatemode-ai.svg -- 0.81kb -> 0.80kb (0.48%)
/src/chrome/icons/providers/dinference.svg -- 0.22kb -> 0.21kb (0.45%)
/src/firefox/icons/providers/dinference.svg -- 0.22kb -> 0.21kb (0.45%)
/src/chrome/icons/providers/evroc.svg -- 2.51kb -> 2.50kb (0.43%)
/src/firefox/icons/providers/evroc.svg -- 2.51kb -> 2.50kb (0.43%)
/src/chrome/icons/providers/siliconflow-cn.svg -- 0.76kb -> 0.76kb (0.38%)
/src/firefox/icons/providers/siliconflow.svg -- 0.76kb -> 0.76kb (0.38%)
/src/firefox/icons/providers/siliconflow-cn.svg -- 0.76kb -> 0.76kb (0.38%)
/src/chrome/icons/providers/siliconflow.svg -- 0.76kb -> 0.76kb (0.38%)
/src/chrome/icons/providers/v0.svg -- 0.79kb -> 0.79kb (0.37%)
/src/firefox/icons/providers/v0.svg -- 0.79kb -> 0.79kb (0.37%)
/src/chrome/icons/providers/openai.svg -- 1.67kb -> 1.66kb (0.35%)
/web/assets/providers/openai.svg -- 1.67kb -> 1.66kb (0.35%)
/src/firefox/icons/providers/openai.svg -- 1.67kb -> 1.66kb (0.35%)
/src/chrome/icons/providers/nova.svg -- 1.58kb -> 1.57kb (0.31%)
/src/firefox/icons/providers/nova.svg -- 1.58kb -> 1.57kb (0.31%)
/src/chrome/icons/providers/deepseek.svg -- 2.11kb -> 2.11kb (0.28%)
/web/assets/providers/deepseek.svg -- 2.11kb -> 2.11kb (0.28%)
/src/firefox/icons/providers/deepseek.svg -- 2.11kb -> 2.11kb (0.28%)
/src/chrome/icons/providers/vultr.svg -- 2.17kb -> 2.16kb (0.27%)
/src/firefox/icons/providers/vultr.svg -- 2.17kb -> 2.16kb (0.27%)
/src/chrome/icons/providers/llama.svg -- 1.13kb -> 1.12kb (0.26%)
/src/firefox/icons/providers/llama.svg -- 1.13kb -> 1.12kb (0.26%)
/src/chrome/icons/providers/poe.svg -- 3.61kb -> 3.60kb (0.24%)
/src/firefox/icons/providers/poe.svg -- 3.61kb -> 3.60kb (0.24%)
/src/chrome/icons/providers/friendli.svg -- 2.14kb -> 2.14kb (0.23%)
/src/firefox/icons/providers/friendli.svg -- 2.14kb -> 2.14kb (0.23%)
/src/chrome/icons/providers/unsloth.svg -- 16.12kb -> 16.09kb (0.22%)
/src/firefox/icons/providers/unsloth.svg -- 16.12kb -> 16.09kb (0.22%)
/src/chrome/icons/providers/bailing.svg -- 1.59kb -> 1.59kb (0.18%)
/src/firefox/icons/providers/bailing.svg -- 1.59kb -> 1.59kb (0.18%)
/src/chrome/icons/providers/baseten.svg -- 1.59kb -> 1.59kb (0.18%)
/src/firefox/icons/providers/baseten.svg -- 1.59kb -> 1.59kb (0.18%)
/src/chrome/icons/providers/ollama.svg -- 3.21kb -> 3.21kb (0.18%)
/src/firefox/icons/providers/ollama.svg -- 3.21kb -> 3.21kb (0.18%)
/web/assets/providers/ollama.svg -- 3.21kb -> 3.21kb (0.18%)
/src/chrome/icons/providers/xiaomi.svg -- 1.69kb -> 1.69kb (0.17%)
/src/firefox/icons/providers/xiaomi.svg -- 1.69kb -> 1.69kb (0.17%)
/src/chrome/icons/providers/alibaba-coding-plan-cn.svg -- 2.01kb -> 2.01kb (0.15%)
/src/chrome/icons/providers/alibaba-coding-plan.svg -- 2.01kb -> 2.01kb (0.15%)
/src/firefox/icons/providers/alibaba-coding-plan-cn.svg -- 2.01kb -> 2.01kb (0.15%)
/src/firefox/icons/providers/alibaba-coding-plan.svg -- 2.01kb -> 2.01kb (0.15%)
/src/chrome/icons/providers/aihubmix.svg -- 2.19kb -> 2.19kb (0.13%)
/src/firefox/icons/providers/aihubmix.svg -- 2.19kb -> 2.19kb (0.13%)
/src/chrome/icons/providers/moark.svg -- 2.25kb -> 2.25kb (0.13%)
/src/firefox/icons/providers/moark.svg -- 2.25kb -> 2.25kb (0.13%)
/src/chrome/icons/providers/ollama-cloud.svg -- 5.54kb -> 5.54kb (0.12%)
/src/firefox/icons/providers/ollama-cloud.svg -- 5.54kb -> 5.54kb (0.12%)
/src/chrome/icons/providers/cerebras.svg -- 3.28kb -> 3.27kb (0.12%)
/src/firefox/icons/providers/cerebras.svg -- 3.28kb -> 3.27kb (0.12%)
/src/chrome/icons/providers/iflowcn.svg -- 2.61kb -> 2.60kb (0.11%)
/src/firefox/icons/providers/iflowcn.svg -- 2.61kb -> 2.60kb (0.11%)
/src/chrome/icons/providers/venice.svg -- 4.24kb -> 4.23kb (0.09%)
/src/firefox/icons/providers/venice.svg -- 4.24kb -> 4.23kb (0.09%)
/src/chrome/icons/providers/google-vertex.svg -- 10.98kb -> 10.97kb (0.09%)
/src/firefox/icons/providers/google-vertex.svg -- 10.98kb -> 10.97kb (0.09%)
/src/chrome/icons/providers/kimi-for-coding.svg -- 6.65kb -> 6.65kb (0.04%)
/src/firefox/icons/providers/kimi-for-coding.svg -- 6.65kb -> 6.65kb (0.04%)
/src/chrome/icons/providers/pollinations.svg -- 7.27kb -> 7.26kb (0.03%)
/src/firefox/icons/providers/pollinations.svg -- 7.27kb -> 7.26kb (0.03%)
/src/chrome/icons/providers/deepinfra.svg -- 14.55kb -> 14.54kb (0.03%)
/src/firefox/icons/providers/deepinfra.svg -- 14.55kb -> 14.54kb (0.03%)
/web/assets/browser-edge.svg -- 3.72kb -> 3.72kb (0.03%)
/src/chrome/icons/providers/meganova.svg -- 11.54kb -> 11.54kb (0.03%)
/src/firefox/icons/providers/meganova.svg -- 11.54kb -> 11.54kb (0.03%)
/web/assets/browser-firefox.svg -- 10.23kb -> 10.23kb (0.01%)
/src/chrome/icons/providers/lucidquery.svg -- 78.13kb -> 78.13kb (0%)
/src/firefox/icons/providers/lucidquery.svg -- 78.13kb -> 78.13kb (0%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
… locator, content-script self-heal, candidate cache

- Recipient-guard probe no longer treats "inconclusive" as blockable: added
  proven-non-send classifiers (composer utilities like "Save & close" /
  "Minimize" / formatting / attach, far-from-composer controls, no-composer
  pages) so ordinary clicks on LinkedIn/Gmail dispatch instead of looping.
- Read typed-but-not-chipified recipients from To/Cc/Bcc input values, plus
  generic recipient fields (type=email, autocomplete=email, multilingual
  To/recipient labels) and address chips (mailto:, [data-email], [email]) —
  confirm-then-send now works on any site, not just Gmail.
- click({text}) resolves reliably: collapse matches that share an actionable
  ancestor (label-wrapped "Send" buttons), short contains needles need a word
  boundary (fixes click({text:"X"}) matching 13 controls), ambiguity is
  narrowed by the hit-target ("receives events") rule and auto-resolved when
  exactly one candidate survives.
- _clickTextCandidates is cached per scope and invalidated by one
  attribute-filtered MutationObserver, removing a full-DOM walk from every
  text click, preflight, and retry.
- Self-healing after extension reload: a generation counter replaces the
  boolean double-injection guard so the newest install always takes over, and
  the message dispatcher always answers (sync throws and empty results become
  explicit errors instead of a silently closed channel).
…n, silent-reply recovery, screenshot budget

- Recipient guard no longer blocks unclassifiable actions — only a confident
  send classification reaches verification; everything else dispatches.
- A bound recipient clarification authorizes the send even when the planner's
  target differs: guard.messaging is re-pointed at the observed recipients,
  approvals are remembered per-recipient for the task (guard.approvedRecipients),
  and a "send all remaining" answer covers the rest of a multi-email task
  (guard.messageRecipientApprovedAll).
- The mismatch block names the page-observed recipient and prescribes the exact
  clarify call (address as an option + "Send all remaining" + Cancel) instead
  of looping.
- Generic surfaces with no recipient identity (contact/feedback forms) fail
  open to the submit-confirmation gate instead of looping.
- Silent content-action replies (undefined) force-inject the current content
  scripts and resend once, with a precise staleContentScript error if that
  still fails.
- _shouldAutoScreenshot is repetition-aware: first action of a burst captures,
  then only every 4th; a different action resets; honors domEvidenceProven and
  the existing maxScreenshotsPerTurn budget. An 8-click burst now costs ~2
  screenshots + 2 vision calls instead of 8 + 8.
- Recipient verification is armed on any URL, not just Gmail/LinkedIn/Douyin.
  Content-side recipient extraction decides whether the page is actually
  sending something — no address and no conversation header means nothing is a
  send and nothing is blocked.
- GENERIC_MESSAGING_SURFACE_RE / GENERIC_MESSAGING_MAIL_LIKE_RE (mail/webmail
  and chat hosts, plus generic /mail /messages /chat /dm /compose /inbox
  routes) only select the verification shape: mail-like surfaces accept a
  To/Cc/Bcc set (supportsRecipientSets), chat-like surfaces keep the strict
  single-conversation-identity rule.
- playClarifySound() plays the completion chime asset when renderClarifyCard
  renders a clarification or permission card, so the user hears immediately
  when the agent needs input. Respects the existing notify-sound setting and
  is best-effort (autoplay-blocked browsers just skip it).
@esokullu
esokullu merged commit 744125e into webbrain-one:main Sep 21, 2026
1 of 2 checks passed
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.

4 participants