Skip to main content
fastbrowse

A browser agent that picks instead of generating.

Jev chooses each action, an LLM plans and reads, and code owns verification, safety and secrets.

python license status


Why

Most browser agents generate each action from a screenshot. fastbrowse indexes the page into candidates and has Jev, a choice model, pick one, so it cannot click something that was never on the page. Every claim in an answer cites a quote stored verbatim from the page, and Jev checks each claim against its quote.

Six live tasks, two passes each, against hosted Browser Use on the same day: the latest httpx version on PyPI (as text and as structured output), the top Hacker News story, httpx's license on GitHub, the year of Gödel's incompleteness theorems via Wikipedia search, and a saucedemo login and add-to-cart. Each answer is graded against the live source (method):

passed correct answer median time mean time cost per task
fastbrowse (cloud browser) 12/12 12/12 12.9s 15.4s $0.0072
hosted Browser Use 11/12 11/12 14.7s 25.8s $0.3767

Speed. fastbrowse beats hosted Browser Use on median and mean at about a fiftieth of the cost. Best successful run per task, fastbrowse against hosted: pypi-version 9.5s against 18.1s, pypi-structured 11.8s against 15.7s, saucedemo-cart 20.0s against 90.7s; hosted is still ahead by 1 to 2.6s on hn-top, github-license and wiki-godel. What did it: a direct address for the task proposed while the start page loads, a plan written from the task alone on a small model, settling on DOM quiet instead of every image and tracker, short facts picked by Jev, hedged requests against provider tails, and no low-confidence recovery for steps that do not act (details).

Twelve runs is a smoke test, not a benchmark: single runs swing by 4 to 5 seconds, and one wiki-godel run took 34s on a slow read. passed counts only complete; the hosted miss ended with "Task ended unexpectedly".

How it works

The task is planned and the start page opened in parallel; each step indexes the page, Jev picks an operation and target, code gates it and acts; reads keep verbatim quotes, and the answer cites every claim.

Jev never writes an action, it picks one of the candidates on the page, so it cannot click something that is not there. The LLM plans, reads and writes. Code owns the gates: irreversible actions stop without --authorize, secrets reach models by name only, and every claim in an answer cites a quote from the page. More in docs/design.md.

How it compares

hosted Browser Use jev-ultrafast fastbrowse
Choosing an action LLM generates from a screenshot Jev picks from indexed controls Jev picks from indexed controls
Returns an answer DONE or BLOCKED an answer with quotes, or why it stopped
Reads pages yes no yes, every claim cited
Signing in yes password fields excluded --secret, models see names only
Irreversible actions not gated not gated stop unless --authorize
Browser cloud local Chrome, your profile local Chrome or cloud

jev-ultrafast is Browser Use's navigation agent, with a measured 7.1 second Google Flights run, and fastbrowse shares its core techniques (one browser call per page read, operation and target chosen in one Jev request). The column describes its main branch as of 2026-09-18; an experimental branch adds a planner with requirement checks.

Try it

Needs Python 3.14, uv, and Chrome (not needed with --cloud).

git clone https://github.com/agent-labs-dev/fastbrowse.git && cd fastbrowse
uv sync
cp .env.example .env            # add AI_GATEWAY_API_KEY or TYPESAFE_API_KEY, and OPENROUTER_API_KEY
uv run fastbrowse "What is the title of the top story right now?" --start https://news.ycombinator.com/
   0 read  -> executed
complete ($0.0071, 1 steps)
The top story on Hacker News is titled "...".

Steps go to stderr and the answer to stdout. --json prints every step, the quotes behind the answer, and cost by component.

Flag Effect
--start URL required: the page to open first
--cloud use a Browser Use Cloud browser (BROWSER_USE_API_KEY); far less likely to be bot-challenged. Prints a URL to watch it live
--headed show the local Chrome window
--profile DIR keep the local Chrome profile in DIR, so a site signed into there stays signed in
--authorize allow submit, pay, delete and send; without it the run stops at needs_confirmation first
--secret NAME=ENV_VAR let the agent type $ENV_VAR on the start origin; models only see NAME
--bitwarden ITEM let the agent type that vault login's username and password, only where the item's saved URIs and their match detection allow
--max-steps N, --max-dollars N bound the run
--downloads DIR keep downloaded files
--json full result instead of the answer
--record FILE save an MP4 of the tab that ends on the answer, time and cost (needs ffmpeg). It shows what the pages showed, so watch it before sharing
export SAUCE_PASSWORD=secret_sauce
uv run fastbrowse "Log in as standard_user with the saved password and add the backpack to the cart." \
  --start https://www.saucedemo.com/ --secret password=SAUCE_PASSWORD --authorize

Signed-in sites

Sign in once by hand in a profile of its own, then point runs at it. The agent reuses the session and never sees a password.

google-chrome --user-data-dir="$HOME/.fastbrowse/amazon" https://www.amazon.com/   # sign in, then close Chrome
uv run fastbrowse "Add a UGREEN USB-A to USB-C cable, 2m, to my cart." \
  --start https://www.amazon.com/ --profile ~/.fastbrowse/amazon --headed

Or sign in from your vault: with the Bitwarden CLI signed in, name the item. The models see only the names username and password; the values stay in this process and are typed only on a site the item's saved URIs cover. With --profile, later runs stay signed in.

export BW_SESSION="$(bw unlock --raw)"
uv run fastbrowse "Add a UGREEN USB-A to USB-C cable, 2m, to my cart." \
  --start https://www.amazon.com/ --bitwarden Amazon --profile ~/.fastbrowse/amazon --headed

Models

The LLM defaults to google/gemini-3.8-flash at low reasoning effort, with google/gemini-3.5-flash-lite for planning, proposing a direct address and typing field text. Override with FASTBROWSE_LLM_MODEL (every purpose), FASTBROWSE_LLM_MODEL_<PURPOSE> (PLAN, READ, FIELD_TEXT, SHORTCUT, RECOVER, COMPOSE, VERIFY) and FASTBROWSE_LLM_REASONING (low, medium, high). Flash-lite for every purpose is faster but scored 8/12 live, so it is used only where its output is checked downstream.

Results

The exit code is 0 only for complete.

Status Meaning
complete every information requirement is backed by a quote, and every action is confirmed on the page
unverified it believes it finished but could not back every claim
needs_confirmation stopped before an irreversible action; re-run with --authorize
needs_login a sign-in wall that no --secret covers
needs_input a field needs a value you did not give, which is never invented
stuck recovery ran out without the page moving
budget_exceeded a step, call, time or dollar limit was reached
observation_limit the page has more controls than Jev can take in
error a model or browser failure

Embed it

import asyncio

from pydantic import BaseModel

from fastbrowse import run_task
from fastbrowse.models import Limits


class Release(BaseModel):
    package: str
    version: str


async def main() -> None:
    result = await run_task(
        "Find the httpx package and report its name and latest released version.",
        start="https://pypi.org/",
        output_schema=Release,
        limits=Limits(max_dollars=0.10),
    )
    print(result.status, result.data, f"${result.cost.known_dollars:.4f}")
    for evidence in result.evidence:
        print(f'  "{evidence.quote}" from {evidence.url}')


asyncio.run(main())
complete {'package': 'httpx', 'version': '0.28.1'} $0.0114
  "httpx 0.28.1" from https://pypi.org/project/httpx/
  "pip install httpx" from https://pypi.org/project/httpx/

run_task builds the browser and clients, runs the agent, and closes the browser on every path. The result has status, answer, data, evidence, final_url and an itemized cost.

Jev comes from Typesafe directly or through the Vercel AI Gateway, whichever key is set; with both, FASTBROWSE_JEV_SOURCE picks one, and FASTBROWSE_JEV_BASE_URL sends it through a proxy. Anything else, such as a cache or a recorded fixture, can be passed as run_task(jev=...): an object with one evaluate(state, questions) method (the JevClient protocol in jev.py). The LLM works the same way.

Safety model

  • Irreversible actions. Before any button or submit, Jev is asked whether it commits something that cannot be undone. Without --authorize, a yes stops the run. This is a classifier, not a guarantee: a page can word a harmful control to look harmless.
  • Secrets. Models see secret names only. A value is resolved at the moment of typing, only for its declared origin, and is redacted from everything the run returns, in raw, URL-encoded and JSON-escaped form. A password field is typed only from a stored secret, never generated.
  • Page content is data. Every prompt says so, and completion is judged against quotes and page state rather than the model's say-so.

Evals and development

uv sync --all-extras                                         # the hosted-arm SDK too, which pyright checks
uv run python -m fastbrowse.evals.runner                     # local fixtures, under half a cent a task
uv run --extra browser-use python -m fastbrowse.evals.live   # live head-to-head; --arms fast skips hosted
uv run ruff format . && uv run ruff check . && uv run pyright && uv run pytest
uv run python scripts/no_slop.py && uv run vale sync && uv run vale README.md docs src scripts tests

Grades come only from things the agent cannot write: requests the fixture server recorded, truth from a site's own API, or the URL the browser ended on. See docs/evals.md, docs/design.md, and docs/jev.md for every Jev assumption checked against Typesafe's documentation.

License

MIT, copyright Agent Labs. Adapted third-party code is credited in NOTICE.

Release files for fastbrowse 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastbrowse 0.2.0
File Size Uploaded
fastbrowse-0.2.0.tar.gz 164.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastbrowse 0.2.0
File Interpreter ABI Platform
fastbrowse-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 283.4 kB

Release files / fastbrowse-0.2.0.tar.gz

Download URL fastbrowse-0.2.0.tar.gz
Size 164.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ff8271f226100d2cedb82d87314c4ded989755061c829654f91cab98723a5a60
BLAKE2b-256 checksum
How to use checksums
c8fce6ae91c104124c36f753cf70b5e2c83819b1b45d114025ef3c0c7dd835e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / fastbrowse-0.2.0-py3-none-any.whl

Download URL fastbrowse-0.2.0-py3-none-any.whl
Size 119.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
03704cc000e377912d1720d332fa4b0185e5a756e0351383d3141f905687acc1
BLAKE2b-256 checksum
How to use checksums
fde3f0c9560b75ccce32326b8688b330a0233c18644d4dc03b291b393e06e519
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page