Jev Ultrafast: 25% Faster Browser Agents via Multiple-Choice Over Screenshots
The article details browser-use's Jev Ultrafast experiment, which replaces screenshot-based observation with a single-request multiple-choice model (Jev) to decide actions and target elements, reducing median task time from 9.45s to 7.09s (25%) and browser protocol calls from 1092 to 101, while adding safety validations and acknowledging limitations.
What It Is
Jev Ultrafast is an experimental browser agent from the browser-use lab, MIT licensed, 1,712 lines of code. Its core partner is TypeSafe's Jev — a model that separates "decision" from "text generation": a single forward pass emits typed answers with probabilities, without generating a single token.
The division of labor is clean: Jev decides "what to do" and "which element to act on". Only when the operation is TYPE_TEXT (typing into an input) does it call a small model to generate the string. The demo uses inception/mercury-2.5, generating "Zurich" in 581 ms and "London" in 346 ms.
To run the project:
git clone https://github.com/browser-use/jev-ultrafast.git
cd jev-ultrafast
uv sync
cp .env.example .env # fill TYPESAFE_API_KEY and TEXT_MODEL_API_KEY
uv run jevOpen 127.0.0.1:8766 to see indexed elements, action probability bars, target confidence, and latency. Click "Choose next" to manually confirm a step before execution.
Core Mechanism: One Request, Two Questions
Traditional agents loop "observe → think → act", re-observing before every action. Jev Ultrafast compresses this into one network round-trip.
Each observation produces an indexed element table:
[1] button Change ticket type · Round trip
[2] combobox Where from? · San Francisco
[3] combobox Where to? · empty
[4] textbox Departure · emptyThen it sends one request asking two questions simultaneously : operation (choose from CLICK / TYPE_TEXT / SELECT / SCROLL_UP / SCROLL_DOWN / WAIT / DONE / BLOCKED) and target (which element). Jev returns probability distributions for both answers.
A design called speculative fan-out is used: the target question is "guessed" — the model simultaneously answers the target for CLICK, TYPE_TEXT, and SELECT. But each target head only contains compatible elements — only if the operation actually selects CLICK is the click target's answer executed. Wrong guesses never click the wrong thing.
In code, this constraint is concrete: when building the request, only three interaction actions (click / fill / select) go into the target table; the rest go to controls. After the operation answer arrives, only the target head corresponding to the chosen operation is validated; other heads' answers are discarded even if they have the highest probability. SELECT adds another layer: the target is not just an element index but index:option_index, and dropdown options carry their own indices.
The response also carries two validation layers: the answer must be in the legal candidate set; the probability dictionary keys must exactly match the candidate set, each value a finite float 0–1, sum within 0.02 of 1, and the chosen item's probability must be the maximum. Any violation invalidates the entire decision — no action is executed.
Where the Speed Comes From: Numbers
The project ran a controlled experiment: six alternating runs, same task, same Chrome profile, same models ( jev-1.13.0 + mercury-2.5), only the runtime implementation swapped. Three paired results: 11.214s vs 6.964s, 8.984s vs 7.913s, 9.450s vs 7.092s — every pair faster after optimization, both sides passed independent verification. Median latency dropped from 9.450s to 7.092s, a 25% reduction.
But the more striking number: browser protocol calls fell from 1,092 to 101 . Reason: the original invalidated decisions on every DOM mutation (including animations), repeatedly reading the accessibility tree and parsing hundreds of DOM nodes; the new version reads common HTML/ARIA controls in one browser call. Jev requests also dropped from 22 to 17, median latency 178 ms.
Other details: the flight-search step executed in 5.217s; from search to final verification took another 1.856s — this includes Google results loading and state changes, deliberately left uncut in the recording.
Cost: the full recording used 90,558 input tokens and 6,325 output tokens across all Jev requests; two text generations cost $0.00006272 on OpenRouter.
The author honestly notes statistical limits: only three pairs, two-sided sign test p = 0.25, this is not a general agent benchmark — Google, network, routing, and browser cache are all live.
Two additional smoke tests: opening Wikipedia's Gödel incompleteness theorem page in 2.798s; local hotel search with filtering in 1.896s.
Waiting Has Nuance
After filling a combobox, the page often pops up suggestions. If Jev is asked before the overlay appears, it can only choose from incomplete options. So a short event-based wait was added: wait until suggestions are visible, capped at 200 ms. Other interactions wait at most two animation frames or 50 ms. These waits happen after the action is recorded and are not counted in decision latency.
Another easily overlooked detail: "send only visible text". Off-screen long text and footers are excluded from the model context — Google Flights' infinitely extending city recommendation lists are a typical example; including them would waste tokens and disturb decisions.
Finally, on retries: interrupted text requests can be reused, but only if the entire text assistant's input hasn't changed by a single byte. If the page changed, regenerate; cannot reuse an old context's answer on a new page.
Safety Boundaries Drawn Precisely
The biggest risk in such projects is letting model output directly become selectors, coordinates, or executable JavaScript. This project blocks every step:
Target must come from observed DOM nodes , not model-invented IDs. Before execution, re-check page freshness and click occlusion; occluded controls are rejected.
Validate context before click : compare content near the target element, document state, form state. Mere animations do not trigger re-evaluation.
Text assistant output must be valid minimal JSON with only a text key; parsed before typing into the input. In the demo, "Zurich" and "London" were genuinely generated, not hard-coded candidates.
Hidden tabs stay rendered , using focus simulation to avoid background animation throttling, but without switching Chrome's visible tab.
Limitations Admitted Frankly
The DOM reader supports common HTML and ARIA controls but does not implement the full accessible-name algorithm, nor traverse shadow roots and iframes. Canvas, file upload, new tabs, nested scrolling, arbitrary keyboard components are not in this MVP.
A more fundamental point: DONE does not equal success . Even if the model says it's done, an independent verification step is still required — hence the independent result checker that confirms one-way setting, Zurich, London, September 20, and that a flight list actually appears on screen. It only searches flights; it does not select or book.
An interesting detail: the docs retain a section "Attempts Rejected During Development", listing each candidate's time and failure reason — the 8.697s version that directly read/wrote DOM failed because name and value extraction was incomplete, failing independent verification. Publishing failed paths is uncommon in open-source projects.
Where This Project Stands
Two things must be clear.
First, this is not a mature product . It has 3 commits, one author (browser-use's gregpr07), and hasn't been updated since September 18. It's more like an architecture experiment from browser-use: proving that "no screenshots, dynamic-indexed action space" can push browser agents to second-level latency. The 23,515 stars reflect the browser-use brand and the idea's value, not code maturity.
Second, it and the earlier rizzo-flow are two layers of the same idea . Rizzo Flow packages Jev's "multiple-choice only" model into a general decision engine; Jev Ultrafast plugs that engine into a browser to verify real-world web performance. One is the engine, the other is the car driven a stretch.
If you've felt the pain of "why are browser agents so slow" — a simple form fill taking 10+ seconds, worrying it'll click the wrong place — this project gives a concrete answer: replace "look at picture, speak" with "choose from numbered list", merge two decisions into one round-trip, change "treat every DOM micro-mutation as failure" to "validate once right before click". It's far from production-ready, but the data shows exactly where the saved time went.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Geek Labs
Daily shares of interesting GitHub open-source projects. AI tools, automation gems, technical tutorials, open-source inspiration.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
