Agent and MCP guides · 2026-09-17

What is Jev? TypeSafe's choice-based decision model for browser agents

TypeSafe's Jev model produces structured decisions such as choices, scores and truthfulness ratings instead of free text. Read how jev-ultrafast applies this to browser agents, the speed difference measured in its own docs, and where the architecture's limits are.

Flow diagram showing elements on a browser page indexed and a single request asking Jev for an operation and a target, with a small language model only stepping in for the text-typing action.

What are Jev and TypeSafe?

Jev is the flagship member of what TypeSafe calls its "System One" model family. Its job is not free text generation; it makes structured decisions: choosing from a list (Choice), scoring a state against a rubric (Score), or rating how true a statement is on a 0-to-1 scale (Noul). The company's own landing page sums this up as "Ask Jev, up to a million times."

The point of the design is parallelism: every question in one request is evaluated against the same state, independently and at once. According to TypeSafe's documentation, adding a question barely affects response time, because questions are processed in isolation and in parallel. The recommended design philosophy is to split a complex decision into small, well-scoped questions rather than one large one, and combine the results in code.

The usual slowness of browser agents

A common agent architecture takes a screenshot, sends it to a vision model, has the model answer in free text such as "click this coordinate," and has code parse and execute that text. Every step of that loop carries the cost of image processing, free-text generation and parsing; as step count grows, the number of low-level protocol calls made to the browser grows with it.

In jev-ultrafast's own measurement, this older approach needed a median of 1,092 browser protocol calls to complete the same task. The problem is not one slow step; it is the fixed cost each step carries, added up.

jev-ultrafast: separating the decision from the text

jev-ultrafast is an MIT-licensed open-source demo published jointly by Browser Use and TypeSafe. Every page observation produces an indexed table of visible controls (buttons, comboboxes, text fields). One Jev request asks which operation to perform (CLICK, TYPE_TEXT, SELECT, SCROLL_UP, SCROLL_DOWN, WAIT, DONE, BLOCKED) and, at the same time, a candidate target for every operation that is currently valid; the executor only consumes the target answer for the operation that was actually chosen.

So the operation and target decisions happen in one network round trip instead of two serial calls. An actual text-generating language model only gets involved when TYPE_TEXT is chosen, and only to produce the value for that one field; it never decides the operation or the target. The browser connection itself runs through a separate open-source component, Browser Harness.

The speed difference measured in the source project

The table below comes from jev-ultrafast's own measurement file; it has not been independently reproduced by LLMTR. The source itself states plainly that this is not a general reliability benchmark, but a few repeats of one task on one browser profile.

jev-ultrafast measurements — Source: jev-ultrafast measurement file (checked 17 September 2026)
MeasurementValueNote
Zurich → London, Google Flights7.1 seconds (7,073 ms)Starts after the first page observation; includes model calls, generated text and loading waits
Median task time, six alternating runs9.450 s → 7.092 s (25% reduction)Same task, same browser profile, same models and settings
Median browser protocol calls1,092 → 101Same six runs; both versions passed 3/3
Opening a Wikipedia article2.798 sSeparate, single-task measurement, same decision policy
Local hotel search/filter task1.896 sSeparate, single-task measurement, same decision policy

Limits and the need for independent verification

A DONE choice is not proof that the task actually succeeded; even the source's own guidance recommends an independent verification step. Coverage is limited too: shadow DOM, iframes, canvas, file uploads, pop-ups and nested scrolling are explicitly left out of this first version.

Working on two example sites (Google Flights, Wikipedia) is not proof of general reliability, and the source says as much: the policy is generic, but two websites do not establish broad reliability. A valid operation choice can still be the wrong one.

Why this architecture is being talked about now

AI agents that can control a browser are spreading quickly across different providers and open-source projects, and they all share the same trade-off: how much image processing and free-text generation each step needs, and what that costs in latency and money. jev-ultrafast answers that trade-off concretely by reducing decision-making to a choice and compressing free-text generation into the one moment it is actually needed — the value written into a field.

That separation has a practical consequence too: the text-generation step becomes an ordinary OpenAI-compatible request, independent of the decision engine. That makes it portable to architectures where a different system makes the decisions.

Beyond browser agents: where this helps in your code

The job Jev does is not specific to browser agents. Every place in your code where you have thought "I would ask a language model this, but then I would have to parse the answer" fits the same shape: turn the decision into a typed question and keep the threshold in code.

The table below shows that shape across four different jobs. The common thread is the last column: the model does not make the decision, it supplies the input to the decision.

One pattern, four different jobs
JobQuestionsWhat the code does
Support ticket routingdepartment (Choice), urgent (Noul), frustration (Score)Picks the queue; weights urgency and frustration into a priority
Moderation queueOne Noul per policyA separate threshold per policy; publishes automatically when all are low, escalates when one is high
Relevance filter before RAGchunk_relevant (Noul), for each candidate chunkDrops anything below the threshold so fewer tokens reach the language model
Instead of fragile parsingformat (Choice) over the expected formats plus an 'other' optionReplaces a chain of regexes; a new format adds an option rather than a pattern

One request, four questions, thresholds in code

The function below judges a support ticket with four questions in a single request. Three things in it are worth noticing.

First, the questions travel together. Questions in one request are evaluated in parallel and independently, so adding one does not noticeably lengthen the response; it adds that question's tokens. That is why the refund question is asked on every ticket: it only matters for billing tickets, and asking anyway is cheaper than a second round trip.

Second, the definition of high priority lives in the code. The model returns probabilities; you set the weights and the cut-off. When the team changes what counts as urgent, a coefficient changes and no prompt is rewritten.

Third, the decision goes to a person when the distribution is not peaked. That is what the confidence field is for: drawing the line between acting automatically and asking someone.

Support ticket triage in one request

import os, requests

QUESTIONS = {
    "departman": {
        "type": "choice",
        "instructions": "Bu talebi hangi ekip karsilamali?",
        "criteria": {
            "faturalama": "Odeme, fatura, iade",
            "teknik": "Hata, kesinti, entegrasyon",
            "satis": "Fiyatlandirma, hesap acma",
            "diger": None,
        },
    },
    "acil": {
        "type": "noul",
        "instructions": "Mesaj zaman baskisi bildiriyor mu?",
    },
    "memnuniyetsizlik": {
        "type": "score",
        "instructions": "Musteri ne kadar rahatsiz gorunuyor?",
        "criteria": ["Sakin", "Rahatsiz ama nazik", "Cok ofkeli"],
    },
    # Yalnizca faturalama kaydinda ise yarar; yine de ayni istekte sorulur.
    "iade_talebi": {
        "type": "noul",
        "instructions": "Musteri para iadesi istiyor mu?",
    },
}


def triage(ticket: str) -> dict:
    res = requests.post(
        f"{os.environ['LLMTR_BASE_URL']}/v1/systemone",
        headers={"Authorization": f"Bearer {os.environ['LLMTR_API_KEY']}"},
        json={"model": "typesafe/jev", "state": ticket, "questions": QUESTIONS},
    )
    res.raise_for_status()
    a = res.json()["answers"]

    # Esikler ve agirliklar TEK yerde. Model yalnizca olasilik dondurur;
    # "yuksek oncelik" tanimi sizin kodunuzda yasar ve bir katsayi
    # degistirilerek revize edilir.
    oncelik = 2 * a["acil"]["noul"] + a["memnuniyetsizlik"]["score"] / 2

    return {
        "kuyruk": a["departman"]["choice"],
        "oncelik": "yuksek" if oncelik > 1.5 else "normal",
        # Dagilim tepe yapmadiysa karari insana birak.
        "insana_devret": a["departman"]["confidence"] < 0.7,
        "iade_akisi": a["iade_talebi"]["noul"] > 0.8,
    }

When it is the wrong tool

If you need free text, this model does not do that job: producing a summary, a draft reply or an explanation needs a chat model. Combining both in one flow is normal, with the decision going to Jev and the wording to a chat model.

Do not compress a judgment that needs extended reasoning, or that weighs several independent factors, into one question; decompose it and combine the answers in code. Rather than scoring a startup pitch in a single question, ask about market size, technical feasibility and differentiation separately and weight them with your own formula. That is both more reliable and revisable afterwards.

It is also the wrong tool when you need the reasoning behind a decision as text: what comes back is a probability distribution, not an explanation. The distribution is often a more useful signal than a rationale, but it is not the same thing.

Where LLMTR fits in this architecture

LLMTR can serve both steps of this architecture. The small language model called on the TYPE_TEXT operation is a standard OpenAI-compatible chat completions request — exactly the endpoint shape LLMTR serves.

The decision step has an option too: Jev is in the LLMTR catalog as `typesafe/jev` and answers on the `/v1/systemone` endpoint. Same `state` and `questions` body, same response shape; the only change is where the request goes and which key it carries. The Structured Decisions documentation linked below covers every request and response field.

You can move the two steps independently: the text-generation step only, the decision step only, or both. The environment variable changes, the actual request shape, and what to watch for are covered step by step in this series' integration guide.

Frequently asked questions

What is Jev?

Jev is the flagship member of TypeSafe's "System One" model family. It produces structured decisions — choices, scores, and truthfulness ratings — instead of free text, evaluating every question in a request in parallel and in isolation.

Is jev-ultrafast an LLMTR product?

No. jev-ultrafast is an MIT-licensed open-source demo owned by Browser Use and TypeSafe. LLMTR does not own or operate this project; this article only examines its architecture and where it intersects with LLMTR.

Did LLMTR run the speed measurements in this article?

No. The figures come from jev-ultrafast's own measurement file, and the source itself states this is not a general reliability benchmark. LLMTR has not independently reproduced these measurements.

Can I call Jev's decision API through LLMTR?

Yes. Jev is in the LLMTR catalog as `typesafe/jev` and answers on the `/v1/systemone` endpoint, with the same request and response body TypeSafe uses. That was not the case when this article was first published; it was added afterwards. LLMTR also fits the architecture's text-generation step (TYPE_TEXT).

Do I need jev-ultrafast to use this architecture?

No. Splitting decisions into a structured choice API and text generation into a separate, narrow LLM call is not specific to jev-ultrafast; you can build the same separation into your own agent and point the text-generation step at LLMTR.

Related posts