You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Eval times leave out provider outages. A run's seconds in the live and local evals no longer counts time
spent retrying a provider's 503s and dropped requests, which says nothing about the agent; the row's transient_seconds holds what was left out.
Relevance passes send small requests in parallel. Packing a page's Noul questions into as few requests as
Jev's 64k limit allows made each one about 26k tokens, and the gateway answered most of those with 503 until
the retries ran out, adding up to 25s a pass or ending the run unavailable. Questions now go in requests of
about 8k tokens, sent together.
--proxy-country CC picks where the cloud browser browses from. It always browsed from the US, so
amazon.co.uk opened on "Deliver to United States" and a dispatch-country prompt. --proxy-country uk shows the
UK storefront as a UK visitor sees it. A country on a local or attached browser is refused, since that
browses from the machine's own IP. The Python API's proxy_country gains its command-line surface.
A link's name no longer includes a nested stylesheet. Amazon puts a <style> block inside a result's link,
and the element's name was built from every child's text, so Jev was offered a control named by a page of CSS
and tried to click it. Style, script, noscript and template children no longer contribute to a name.
A dense results page is compacted rather than refused. Amazon's signed-in search results offered Jev 112
products with ~200-character titles and ~480-character tracking links, and the run stopped at observation_limit before it could pick one. When a page does not fit even on-screen only, its elements are now
sent with labels and links shortened before fastbrowse gives up.
The CLI attaches to a browser already running.--cdp-url ws://… drives any browser exposing CDP: a
container, a VM, a hosted browser. The run opens one tab and closes only the tabs it owns, so the browser is
left as it was found. The Python API's cdp_url gains its command-line surface; flags that shape a browser
fastbrowse starts (--local, --headed, --profile, --cloud-profile, and their FASTBROWSE_* environment
counterparts) are refused alongside it.
--bitwarden signs in past an authenticator-app code. A vault item that holds an authenticator key now
also offers one_time_code, the current code computed from the key at the moment it is typed, scoped to the
same origin as the username and password. Amazon's two-step sign-in had stopped a run at "Enter OTP" with the
key in the vault. Base32 keys and otpauth://totp URIs are read locally, so Bitwarden Premium is not needed; a
code with a few seconds left waits for the next one, and a key fastbrowse cannot use (steam://, HOTP) is
refused when the item is read.
A stored username is typed into an email or phone sign-in field. Amazon's sign-in field is labelled
"Enter mobile number or email", and Jev, seeing only a secret named username, chose to write new text,
so the run stopped needs_input before signing in. The field question now says that stored secrets are the
site's sign-in credentials, named by role.
A dense page keeps the controls the task needs, not the first ones in the document. The browser now
indexes up to 320 controls, and when a page offers more than 160, Jev is asked in one batched pass whether each
could serve the task's next actions; the step sees the most relevant 160. Before, a page was cut at its first
160 controls, so a result or filter drawn after a long header and sidebar never reached the choice. Pagers,
blocking fields and controls holding a value or selection are always kept, and a control Jev did not answer
for is kept rather than dropped. A dense page costs one more Jev round trip; a page under the limit costs
nothing more.
A page whose on-screen controls alone outgrow Jev's input no longer ends the run at observation_limit: the
controls that fit are offered, pagers and set fields first, and the rest are reported as omitted so a scroll
can reach them. The run stops there only when the page's state does not fit with no controls at all.
Jev reads short facts on long pages too. Jev's quick read of a fact, such as a version or a date, gave
up on any page with more than 253 quotable spans or more text than its input allows, which was six of ten real
pages measured, from Wikipedia articles to GitHub releases, and the LLM reader then read the page a chunk at a
time. Jev now first judges which passages bear on the requirements, one batched pass, and picks the fact from
those. A requirement Jev calls absent from a narrowed page still goes to the LLM reader, since the evidence may
sit in a passage it set aside.
A field Jev picks from a listing record, such as a release date, now quotes the record up to it, so the
answer's claim that version 0.1.0 shipped that day still has the version in its citation.
A batched Jev pass cut short by the time limit now keeps the cost of the requests that had already answered,
and one the call limit cannot cover counts none of its calls.
A setting switched back to where it was is caught as a loop. A run on a results page could turn a filter
on and off until it ran out of steps: each click changed the page, so no two steps looked alike. When every
control on a page returns to the values it held before an earlier action, the run now stops and asks the
recovery model for a different approach, naming the control and the actions in between.
Recovery remembers its earlier attempts. The recovery model and Jev now see the last few diagnoses and
subgoals of the current stall, and which attempt this is, so a second recovery does not propose the plan the
first one already tried.
A form's Next button no longer ends the run. A click on a "Next" that was not a link to another address
was treated as paging to the next part of a list, and the run stopped on a multi-step form's first step. Only
a link to another page counts as a pager now.
stretch-dev and stretch-heldout eval suites.dev and heldout now pass almost every run, so these
harder tasks (a multi-step form with a correction, a date relative to today, a list aggregated across pages, a
filter applied and partly undone) are what show whether an agent change helps.
Every step is credited to Jev or the LLM, never to "code". A step code dispatches carries out a model's
choice, and is now recorded as that model's: the next page of a list is the reader's, since the reader asked for
the rest of the list, and the read taken before an interaction is Jev's, since Jev judged the page to be
evidence. A refused finish is the verifier's when it ran, and Jev's otherwise. decided_by no longer takes the value code, and recording captions name only Jev or the LLM.
fastbrowse --version prints the installed version, which bug reports now ask for.
A field the task has no value for is skipped before it ends the run. Most such fields are optional: Google
Flights opens a "Where else?" box beside the origin, and a run that picked it stopped needs_input with
nothing searched. The first time, recovery is told the task gives no value and chooses another step; a field
it sends the run back to is a required one, and the run still stops needs_input rather than invent a value.
A finished search is checked on the stronger model. When Jev doubts a run is done, the verifier that has
the last word now runs on google/gemini-3.8-flash rather than flash-lite. On a Google Flights search with
every field right and no nonstop filter, flash-lite took the "Nonstop" rows for the filter and passed it ten
times in ten; the default model refused all ten and passed the filtered search every time. A doubted finish
costs about two seconds more.
The evals allow 50 steps. A fare search on Google Flights took up to 29 steps, one short of the old limit,
so a run that needed a recovery or two could run out of steps rather than fail on its merits.