A browser agent that books a flight from a single line of plain English. TypeSafe's Jev makes every bounded decision, a small text model writes only the strings Jev cannot produce, and ordinary code does the scrolling and clicking.
The run in the video above: 12 browser actions, 15 Jev decisions, 4 calls to the text model, finishing on a held Alaska seat at $131.20.
Most browser agents are slow for one reason: the model talks to itself. It proposes an action, the harness validates it, the action was malformed or pointed at an element that isn't on the page, so it asks again. That loop is where the seconds go, and no amount of prompt tuning removes it, because the model is being asked to be right about something it cannot reliably be right about.
Decide. Bounded choices over a known option set.
Six heads in one request: which tool, what the traveller is optimising for, whether the sentence carries enough to act on, the date, the party size, and one way against round trip.
Write. The one job Jev cannot do.
"Portland" becomes PDX. "March 3" becomes a date. Open-ended string production, nothing else.
Act. Navigate, type, scroll, click.
Driven over the Chrome DevTools Protocol. This was never a model's job.
Decide again. One choice over the fare table, read as numbers.
Twelve options with a price, a duration and a stop count, against a stated priority.
Nothing retries on malformed output, because nothing is asked to produce output it could get wrong. That is the whole speed argument.
From a separate instrumented run, Portland to Denver, where the log drawer recorded every call.
The last segment is the honest one. Two thirds of the clock is Google and the airline painting their own pages, which no agent controls. Wall clock across runs swings between 11.6 and 19.4 seconds for that reason alone. The part Agent One is responsible for is the four seconds of decisions, and warm those run at 133 to 200 ms for routing.
| Run | Outcome | Time | Steps |
|---|---|---|---|
| PDX → SEA, 1 adult | Jev picked $132 from 12 fares | 11.59 s | 9/9 |
| PDX → DEN, 2 adults | Stopped on Frontier passenger info, $268 | 12.88 s | 9/9 |
The obvious approach hands the model the whole page and asks it to click the best flight. On Google Flights that fails, because the cheapest fare usually sits under Other flights, roughly a thousand pixels below the fold. An honest answer to "which of these can I click right now" excludes the row that wins.
So the harness reads the result rows itself and turns them into numbers, then hands Jev a short choice over structured options:
{"price_usd": 132, "total_minutes": 224, "stops": "1 stop",
"airline": "Alaska", "departs": "6:00 AM"}
Jev still decides which one wins. It is simply being asked something a decision model can be right about. The code does the scrolling and the clicking.
book_flight and unclear.
The routing layer is shaped for more; only one is loaded today.