Most AI agent failures are not writing failures. The LLM writes well. It starts on a request that was missing the one detail that mattered, reaches for the wrong tool, says it is done when one part of the job is still missing, or grinds through the same failing step for twenty iterations. Those are judgment calls, the decision making inside an AI agent, and an ordinary agent loop leaves every one of them to the same model that is busy doing the work.
JevAgent gives those calls to someone else. Your LLM still reads the request, uses the tools, and writes every word. Jev, TypeSafe's decision model, makes short, structured judgments at fixed points in the run and never writes the reply. This post walks through each of those points, what Jev asks there, and four problems the split solves.
Anatomy of a JevAgent run
Each Jev check is opt-inRequest arrives
Your model · System 1
Nothing yet. No main-model tokens are spent until Jev lets the run start.
Jev · System 2
Is the request clear? Which specialist should take it? Which tools could help?
14 yes/no · 1 choice · 1 yes/no per tool
- Unclear: the run returns 1 to 6 questions
- Specialist chosen: its own loop runs
Before work
Your model · System 1
Writes the run state: goal, what not to do, the hard part, and named deliverables.
Jev · System 2
Is the scope one example, or every member of a group?
1 choice
Working
Your model · System 1
Calls tools and reasons. A writer keeps a verified brief of the run every few iterations.
Jev · System 2
Do the run's facts and brief say one agent is no longer enough?
12 evidence questions per option
- Clone selected: 1 to 4 copies try in parallel
- Swarm selected: a planned team of 2 to 10 helpers
Finish attempt
Your model · System 1
Claims it is done. A handoff compiles the run's evidence.
Jev · System 2
Is every deliverable and requirement shown in the evidence?
1 batched request · per-item veto
- A check fails: back to the same loop, 3 times by default
Reply
Your model · System 1
The answer stands and is returned to your app.
Jev · System 2
Nothing more to decide. Every verdict and its usage is on the response.
agent.response
In this article
- What is Jev, and how does it work inside an AI agent?Your LLM does the work. Jev makes the calls.
- Preflight questions: make your LLM agent ask clarifying questions firstThe clarity check that runs before your model starts.
- Agent routing and tool selection: the right agent and tools for each requestSpecialist routing, tool selection, skill preload, and read-only runs.
- Continuation gates: stop premature completion when an AI agent says it is doneHow Jev judges each finish attempt and sends work back.
- Dynamic context compaction: a run brief for long-running AI agents that cannot driftThe verified run brief that clones and compute decisions read.
- Mid-run compute: when an AI agent is stuck, run parallel agentsRun facts, evidence questions, clones, swarms, and bulk work.
- Why AI agents fail: four worked examples and the JevAgent check for eachVague requests, early finishes, stalled runs, and routing.
- Observability and Jev pricing: what you can see and what a run costsThe response record and the usage ledger.
- Frequently asked questions about JevAgent and JevShort answers on clarifying questions, early finishes, and cost.
- How to use Jev in an agent: start with one checkWhere to go next.
What is Jev, and how does it work inside an AI agent?
JevAgent borrows the dual-process System 1 and System 2 framing from psychology, Kahneman's fast and slow thinking, and applies it literally to LLM agents. System 1 is your LLM, such as a Claude, GPT, or Gemini model. You pick the provider, the model, the system prompt, the tools, and the loop limits, exactly as you would for any Vidbyte SDK agent. Every reply, tool call, and piece of planning comes from it.
System 2 is Jev. Jev is a decision model, closer to a classifier than to a chatbot: it answers yes/no and choice questions with probabilities, quickly and cheaply, and it cannot write prose. JevAgent sends it a small number of fixed, well-specified questions at fixed points in the run, then code decides what to do with the answers. Thresholds, vetoes, and caps live in the SDK, not in a prompt the model might talk itself out of.
A note on names: TypeSafe calls Jev the first System One model, a name taken from Daniel Kahneman's Thinking, Fast and Slow. Like System 1, Jev makes fast, focused judgments and returns typed answers with probabilities, without writing out its reasoning. JevAgent's labels name roles in a run, not speeds. In Kahneman's account, System 2 monitors System 1 and overrides it when needed, and that is the role Jev plays here. Its speed is what makes those checks cheap enough to run at every decision point.
Because the questions are fixed, the behavior is inspectable. Every check you turn on leaves its outcome and its usage behind, on agent.response or, for the tool selector, in the reply's jev_tool_selector metadata, so you can see why a run stopped to ask, why it went back to work, or why it brought in help.
Independent research has tested a related split. REFLEX (Wu and Lim, 2026) uses Jev as a fast, typed decision layer and calls a strong LLM only when confidence is low or text must be generated. On a 100-task benchmark it reached 95% success with 72.7% fewer strong-model calls than a strong-only agent, though its authors found limited advantages over a cheap generative cascade when ordinary routing is already highly accurate. A study of 2,170 public Jev projects on GitHub (Ling et al., 2026) describes Jev as a reusable decision component whose role varies with the workflow around it.
How does Jev's accuracy compare with Claude or GPT on the same classification tasks? AI/ML API, which resells Jev access, tested Jev 1.13 against Claude Opus 5.5, GPT-6 Sol, and three cheaper LLMs, with reasoning set low or off, on 300 examples per task. On 77-way intent routing, Opus 5.5 and GPT-6 Sol were about 7 points more accurate (85.7% and 85.3% against 78.3%), at $8,243 and $2,321 per million decisions against Jev's $98 at AI/ML API's rates. Jev had the best F1 on content moderation, where it answered in about 140 ms on the server, 6 to 18 times faster than the LLMs, and it ranked last at rating answer quality. The authors conclude that Jev earns its place in front of an LLM rather than as a replacement for one. JevAgent also keeps your LLM for the work and uses Jev only for decisions.
OpenRouter's own benchmark, on the 3,080 customer-support messages and 77 intents of the Banking77 test set, found the same shape: Jev 1.13 reached 81.0% accuracy against 84.4% for Claude Opus 5 with reasoning off, at a median latency of 175 ms against 2,266 ms through OpenRouter, and $0.11 against $2.42 per thousand requests. Jev's confidence on a choice answer is not a calibrated probability, OpenRouter notes, but it ranked its answers well: it was right on 96.3% of answers at 0.99 or above and on 29.6% of those below 0.5. JevAgent's specialist routing does not apply a confidence threshold today.
What are Jev's known limits? For model-card details, TypeSafe's models page lists Jev's versions, prices, and context limits, and a separate page lists nine known failure modes of Jev 1.13. Among them: it reads instructions literally, does not count reliably, reads dates as text, and in some cases leans toward the first option of a choice question. TypeSafe's advice is to keep arithmetic in code, and JevAgent does: code counts the items, removing duplicates when the request asks for distinct ones, before Jev checks OUTPUT_COUNT, code measures the final answer's length for OUTPUT_EXTENT, code checks stage order for REQUIRED_SEQUENCE, and the compute checkpoint reads iteration, tool-call, and token counts straight from the loop. Choice order is one more reason to check response.specialist on real traffic when you use specialist routing.
Your model — Writes every reply, plans, and uses the tools. On SDK main its calls go through the Vidbyte gateway by default, which serves OpenAI, Anthropic, Gemini, xAI, DeepSeek, and Kimi; set
model_mode=TextModelMode.DIRECT(imported fromvidbyte.lib.enums) to call any provider the SDK supports directly, with your own key.Jev — Answers fixed questions with probabilities: a yes/no question, which TypeSafe calls a Noul, returns the probability of “yes”, and a choice question returns a probability for each option. Input costs $0.042 per million tokens and output is free.
Code — Turns Jev's probabilities into actions through thresholds, per-item vetoes, and continuation caps.
A Vidbyte API key — Needed by default since vidbyte-sdk 0.4.0, because model calls go through the Vidbyte gateway unless you choose direct mode (
model_mode=TextModelMode.DIRECT), and Jev checks always use it. In direct mode a provider key alone runs an agent with no checks. Building the agent, or running it with no checks, never calls Jev.
- What it returns
- Your LLMText, tool calls, and plans
- JevProbabilities for yes/no and choice questions
- Its job in the run
- Your LLMDoes the work: every reply, tool call, and plan
- JevMakes the calls: clarity, routing, tools, done, and compute
- Who acts on its output
- Your LLMThe agent loop and your app
- JevSDK code, through thresholds, vetoes, and caps
- Writes prose
- Your LLMYes
- JevNo
| Your LLM | Jev | |
|---|---|---|
| What it returns | Text, tool calls, and plans | Probabilities for yes/no and choice questions |
| Its job in the run | Does the work: every reply, tool call, and plan | Makes the calls: clarity, routing, tools, done, and compute |
| Who acts on its output | The agent loop and your app | SDK code, through thresholds, vetoes, and caps |
| Writes prose | Yes | No |
Create a JevAgent
from vidbyte import (
JevAgent, JevAgentSettings, JevRuntimeSettings, JevPreflightPreset,
)
# pip install vidbyte-sdk, then set VIDBYTE_API_KEY before running.
agent = JevAgent(
JevAgentSettings(
name="support-agent",
system_prompt="Help the user resolve account questions.",
provider="openai",
model_name="gpt-5.4-mini",
),
JevRuntimeSettings(preflight=(JevPreflightPreset.CLARITY,)),
)
reply = agent.run("Summarize the renewal options for the Acme account.")
print(reply.content)Preflight questions: make your LLM agent ask clarifying questions first
A human contractor who gets a vague brief asks a question. An agent usually guesses, and it guesses at full price: a long loop, tool calls, and a confident answer to the wrong question. The clarity check moves that question to the front of the run, where it costs the least. It is ambiguity detection for agent requests: it flags an ambiguous request or an underspecified prompt before the agent starts, and the agent asks clarifying questions instead of guessing.
Telling the agent's own model to ask when unsure is the obvious fix, and research suggests it is not enough. The CLAMBER benchmark (ACL 2024) found current LLMs of limited practical use at identifying and clarifying ambiguous queries, and found that chain-of-thought and few-shot prompting brought only marginal gains and could make the models overconfident. So the clarity check is not an instruction in your system prompt. It is a separate decision model answering fixed questions.
When it is on, Jev reads the request against 14 fixed questions before your model sees anything. Does the request name its target? Does it supply the material the work needs? Does every “this” point at something? The check fails if the average probability of “yes” drops below 0.75, or if any single answer's probability falls below 0.2, so one glaring gap is never averaged away by thirteen clean ones.
If the check fails, JevAgent does not start the main loop. Your model, running with no tools and a fixed prompt, turns the weakest gaps into one to six questions, each with two to four recommended answers. The run returns those questions as its reply and records them on the response. Jev reads only the new message, so your app re-runs the agent with the original request and the user's answers together.
Jev answers the 14 clarity questions
All of them go out in one batched request, with the routing question if routing is on.
Code scores the answers
The check passes when the mean is at least 0.75 and no single answer is below 0.2.
An unclear request stops and asks
Your model writes 1 to 6 questions with recommended answers. The main loop never starts.
Re-run with the answers
Send the original request plus the answers. The gate checks the new message, and work begins.
Handle a clarification
request = "Write the migration report."
reply = agent.run(request)
if agent.response.needs_clarification:
# The run stopped before your model wrote a single token of the report.
answers = []
for item in agent.response.clarification.questions:
choice = ask_user(item.question, item.recommendations) # your UI
answers.append(f"{item.question} {choice}")
# Jev reads only the new message, so send the request and the answers together.
reply = agent.run(request + "\n\nAnswers:\n" + "\n".join(answers))
print(reply.content)The 14 things the clarity check looks at
Each question is answered yes or no with a probability. Each flagged example is a request that fails that one question.
- Action
- What Jev asksDoes the request state an action?
- Flagged example“The login page times out.”
- Object
- What Jev asksDoes each action have something to act on?
- Flagged example“Fix this.”
- Deliverable
- What Jev asksDoes it show the kind of result expected?
- Flagged example“Look into the checkout errors.”
- Target
- What Jev asksDoes it name the target of the work?
- Flagged example“Fix the bug from yesterday.”
- References
- What Jev asksIs every “this” or “it” resolved?
- Flagged example“Explain this error.”
- Scope parts
- What Jev asksDoes it say which parts to cover?
- Flagged example“Refactor the backend.”
- Scope size
- What Jev asksDoes it say how large the result should be?
- Flagged example“Write a summary of the report.”
- Completion
- What Jev asksDoes it state a finish line?
- Flagged example“Make the search page faster.”
- Information
- What Jev asksDoes it supply the material the work needs?
- Flagged example“Review the login code.”
- Constraints
- What Jev asksDoes it state limits for an open choice?
- Flagged example“Design a schema for the app.”
- Priorities
- What Jev asksDoes it order aims that compete?
- Flagged example“Make it faster and use less memory.”
- Consistency
- What Jev asksCan every instruction be followed together?
- Flagged example“Keep the API unchanged and rename an endpoint.”
- Time context
- What Jev asksDoes it fix the time frame the answer depends on?
- Flagged example“What changed in the last release we used?”
- Single reading
- What Jev asksDoes every key word have one meaning?
- Flagged example“Clean up the data.”
| Check | What Jev asks | Flagged example |
|---|---|---|
| Action | Does the request state an action? | “The login page times out.” |
| Object | Does each action have something to act on? | “Fix this.” |
| Deliverable | Does it show the kind of result expected? | “Look into the checkout errors.” |
| Target | Does it name the target of the work? | “Fix the bug from yesterday.” |
| References | Is every “this” or “it” resolved? | “Explain this error.” |
| Scope parts | Does it say which parts to cover? | “Refactor the backend.” |
| Scope size | Does it say how large the result should be? | “Write a summary of the report.” |
| Completion | Does it state a finish line? | “Make the search page faster.” |
| Information | Does it supply the material the work needs? | “Review the login code.” |
| Constraints | Does it state limits for an open choice? | “Design a schema for the app.” |
| Priorities | Does it order aims that compete? | “Make it faster and use less memory.” |
| Consistency | Can every instruction be followed together? | “Keep the API unchanged and rename an endpoint.” |
| Time context | Does it fix the time frame the answer depends on? | “What changed in the last release we used?” |
| Single reading | Does every key word have one meaning? | “Clean up the data.” |
What happens if Jev is unavailable?
The check fails open: an outage or a missing answer lets the run start as usual, and the same is true if the question writer fails. The exception is access. A missing or rejected Vidbyte key, or a gateway refusal for payment or rate limits, raises an error instead of silently skipping the check.
Why yes/no questions instead of one “is this clear?” prompt
A single vague question gets a vague answer. Fourteen narrow questions each have one job, and the weakest ones tell the question writer exactly which gap to ask about, so the user sees three precise questions instead of a generic “can you tell me more?”
Agent routing and tool selection: the right agent and tools for each request
An agent can only do good work with the right instructions and the right tools in front of it. Most teams handle this by growing one system prompt and one tool list until both are too long for the model to use well: an LLM agent with too many tools has more ways to pick the wrong one. JevAgent aligns the agent to the request before the loop starts instead.
Four alignment checks are on SDK main. With agent routing, the main agent acts as a router agent over your specialist agents: Jev decides whether to route to a specialist agent and which one, like a multi-agent router with no routing rules to maintain, and the agent handoff happens before any work starts. Dynamic tool selection narrows a large tool catalog to only the relevant tools, per request. Skill preload adds only the relevant skills' instructions to this run's system prompt. Read-only runs limit a run to SAFE and READ tools when Jev judges that the request asks only for an answer.
Routing rides in the same preflight request as the clarity check. Tool selection sends its own request, so clarity, routing, and tool selection together cost two Jev calls before work begins. The read-only check rides in that first request too, so with clarity or routing on it adds questions but no extra call.
Agent routing picks an agent, not a model. Jev judges only the kind of work a request needs, never the quality, speed, or cost of the model behind a specialist, although each specialist can run on a different model. For model routing, where Jev picks the LLM and reasoning effort for each request, OpenRouter offers Jev Router (typesafe/jev-router, released September 25, 2026), a separate hosted router that runs on Jev. It has no fixed price of its own: each request is billed at the price of the model that serves it.
Give JevAgent a team of specialists, each a title, one sentence of scope, and an ordinary SDK agent. Jev answers one choice question that ranks every scope, plus “none”, by the kind of work the request needs. The top answer wins, with no confidence threshold, so keep scopes few and clearly distinct, and check response.specialist on real traffic. A chosen specialist runs its own loop with its own model and tools, and “none” keeps the task with the main agent.
Route billing to a specialist
from vidbyte import BaseAgent, JevAgent, JevAgentSettings, JevSpecialist
billing = BaseAgent(
name="billing", system_prompt="Resolve invoices, refunds, and plan changes.",
provider="openai", model_name="gpt-5.4-mini",
)
scope = "Invoices, refunds, double charges, and plan changes."
agent = JevAgent(
JevAgentSettings(
name="front-door",
system_prompt="Answer general product questions.",
provider="openai",
model_name="gpt-5.4-mini",
agents=(JevSpecialist("billing", scope, billing),),
),
)
reply = agent.run("I was charged twice for October.")
print(agent.response.specialist) # the specialist that ran, or NoneWith the tool selector on, Jev asks one question per configured tool: could this tool be useful at any point in completing the user's request? It answers yes if the tool could materially help, even when it is not the first tool needed, so the question is lenient on purpose. Tools at or above the threshold (default 0.20) stay, in their original order, and the rest never reach the model. If Jev is unavailable, the full catalog is kept. Tools from MCP servers count too: the tools with_mcp_server brings in join the catalog before the selector runs, so Jev asks about each one like any other tool.
If you have used LangChain's LLMToolSelectorMiddleware, the goal is the same: keep a large tool catalog from crowding the model. The method differs. That middleware asks an LLM, by default the agent's own model, which tools are most relevant, and can cap the list with max_tools. JevAgent asks Jev about each tool separately, so every tool gets its own probability and one threshold decides, with no count to tune.
Narrow a large tool catalog
from vidbyte import JevAgent, JevPreflightPreset, JevRuntimeSettings
runtime = JevRuntimeSettings(
preflight=(JevPreflightPreset.TOOL_SELECTOR,),
tool_selector_threshold=0.2, # keep a tool when P(useful) >= 0.2
)
# analyst_settings: your JevAgentSettings, with e.g. 30 SQL, CRM, and docs tools
agent = JevAgent(analyst_settings, runtime)
reply = agent.run("Which enterprise customers opened the most tickets last week?")
print(reply.metadata["jev_tool_selector"]) # candidate and kept countsOffer skills with JevAgentSettings(alignment=JevAlignmentSettings(skills=[...])). Jev asks one yes/no question per skill, scoring them all in one or more batched requests sent at once. Skills at or above skills_threshold (default 0.5) have their full text added to this run's system prompt only, and each skill's outcome is on agent.response.skills.
InlineSkill — Skill text you pass directly. Plain strings work too.
LocalSkill — A folder with a SKILL.md file.
SkillsShSkill — A skill installed with
npx skills add.GitHubSkill — A skill in a GitHub repository, by repo, ref, and path.
AnthropicSkill and OpenAISkill — A skill uploaded to Anthropic's or OpenAI's Skills API.
Many requests ask only for an answer: why a test fails, whether a plan is safe, which library to use. With the read-only check on, Jev answers eight yes/no questions in the preflight request, each one separate evidence that the request asks for an assessment, such as an explanation, a diagnosis, an opinion, a recommendation, or a plan, and not for a change. Only when every answer reaches 0.75 does the run turn read-only: the agent is offered only SAFE and READ tools, and a permission ceiling refuses any WRITE or EXECUTE tool call from this agent or any agent it starts, including a specialist, clones, and swarm helpers. One clear no, or a Jev outage, keeps the full tool catalog.
Tool calling stays with your LLM, which makes every tool call. Jev never calls a tool: it judges the request, and the SDK enforces the limit in code, so when Jev judges that a request asks only for an answer, the run gets no write or execute permissions. The limit reads each tool's declared permission, and a tool that declares none counts as SAFE, so mark tools that change things as WRITE or EXECUTE. Tools from an MCP server take the server's permission: by default they count as EXECUTE, so a read-only run hides them, while permission=McpToolPermission.READONLY marks every tool on that server as READ, including any that change things, and every permission check reads that mark, not only read-only runs, so use it only for a server whose tools all read. The agent still answers in full, and agent.response.read_only reports whether the limit applied. Read-only runs ship in vidbyte-sdk 0.4.0 and newer; pip install -U vidbyte-sdk gets them.
Answer without changing anything
from vidbyte import JevAgent, JevPreflightPreset, JevRuntimeSettings, ToolPermission, tool
@tool(permission=ToolPermission.WRITE) # a tool that declares no permission counts as SAFE
def apply_patch(path: str, diff: str) -> str:
"""Apply a unified diff to one file."""
...
runtime = JevRuntimeSettings(preflight=(JevPreflightPreset.READ_ONLY,))
# engineer_settings: your JevAgentSettings, with repo tools such as apply_patch
agent = JevAgent(engineer_settings, runtime)
reply = agent.run("Why does the nightly export time out? Explain; don't fix anything yet.")
print(agent.response.read_only) # True when Jev judged the request read-onlyContinuation gates: stop premature completion when an AI agent says it is done
The most expensive agent failure is the one you do not notice: a polished answer that skipped one of the three things you asked for. Agents finish early because the model decides when it is finished, and a model that has produced something reasonable is ready to stop. That is premature completion: the agent says it is done before the task is complete.
Continuation takes that decision away from the model. Before work starts, your model writes a run state: the goal, what not to do, the hardest requirement, and the named deliverables. Each time the agent tries to finish, a handoff compiles the evidence for each item from a numbered log of what actually happened. A deliverable counts when the log shows it was made, not when the final answer promises it, so task completion has to be proven: continuation can verify every deliverable against completion evidence instead of the agent's own summary. This is verification at runtime, not offline evaluation: the check runs inside the run, before the answer reaches your app, and a failure sends the agent back to work instead of only scoring it afterward.
Jev then judges every enabled check in one request. Most checks use their probability threshold as a per-item veto as well as a bar for the average, so one clear “no” sends the agent back even when everything else looks finished. The agent returns to the same loop, with its history and tools intact, carrying a message that lists the original request, the run state, the evidence, the failed checks, and what to focus on. The cap is three continuations by default. After that, the current answer stands and every verdict stays on the response.
If you have used LLM-as-a-judge or agent-as-a-judge setups to grade agent output, this will look familiar. It is a generator-verifier loop: your LLM generates, and Jev, a separate decision model, is the judge model, so the finish does not rest on LLM self-verification. Three things differ from a typical judge. Jev answers fixed questions instead of writing a critique, it reads evidence from the run's own log rather than only the final answer, and its verdict sends the agent back to work instead of lowering a score in a report.
How good is Jev as a judge? Early tests agree on where it is strong. In LangChain's test on one agent, five requests judged 100 times each, Jev matched a human reviewer on all 500 pass/fail decisions, with 92 to 913 times less score variance than GPT-5.6 Luna, GPT-5.6 Terra, and Claude Sonnet 4.6. OpenRouter found it as accurate as an LLM judge on a closed faithfulness check (84 of 88 against 83 of 88) at about a tenth of the latency, but well behind on an open rubric (Spearman 0.47 against 0.72 for summary consistency). A Carnegie Mellon study of 4,850 judgments drew the same line: Jev stays within three points of GPT-6 wherever a verdict can be read off the text, and trails it by 7 to 28 points on expert knowledge, code, math, and logic puzzles. Continuation works in that regime: Jev answers fixed yes/no questions about evidence compiled from a numbered log of the run.
Can Jev work as an LLM guardrail? Arize screened a car-dealership chatbot's incoming messages, draft replies, and tool arguments with Jev and with GPT-5.4 nano, using the same questions and thresholds. Jev's median check took 104 ms against 1,915 ms, the five checks of one attack took 0.7 s against 9.2 s, and both reached the same decisions, though Arize calls it a live demo rather than a controlled accuracy test. JevAgent's own guardrails sit at fixed points of the agent loop: read-only runs cap tool permissions in code, and continuation sends the agent back when the run's evidence misses a deliverable. Tool selection also hides the tools a request does not need, but it is a relevance filter that keeps every tool when Jev is unavailable, not a security limit.
Write down what done means
Your model writes the run state once, before the loop: the goal, what not to do, the hard part, and a section for each enabled check that needs items from the request.
Collect evidence at each finish attempt
A handoff compiles the evidence for every deliverable from the run's responses, tool calls, and a numbered event log. Code assigns the event ids, and stage-order evidence must cite ids that exist in that log.
Judge everything in one request
Jev answers every enabled check's questions together. Each check is scored on its own, with per-item vetoes.
Continue, or let the answer stand
A failure appends a focused continuation message to the same loop, up to three times. A pass, or the cap, ends the run.
Check every deliverable
from vidbyte import JevAgent, JevContinualSettings, JevDoneCheck, JevRuntimeSettings
runtime = JevRuntimeSettings(
continual=JevContinualSettings(
checks=(JevDoneCheck.MULTI_PART, JevDoneCheck.SELF_REVIEW),
max_continuations=3,
),
)
agent = JevAgent(engineer_settings, runtime) # your settings, with repo tools
reply = agent.run(
"Fix the webhook signature bug, add a regression test, "
"and update the on-call runbook."
)
for check, result in agent.response.done.items():
print(check.value, result.passed, result.incomplete)
print("sent back", agent.response.continuations, "times")- When it runs
- Typical LLM-as-a-judgeAfter the run, in an eval pipeline
- JevAgent continuationInside the run, at every finish attempt
- What it reads
- Typical LLM-as-a-judgeThe final answer and a rubric
- JevAgent continuationEvidence compiled from the run's own log
- What it returns
- Typical LLM-as-a-judgeA score or a written critique
- JevAgent continuationProbabilities on fixed questions, with per-item vetoes
- What a failure does
- Typical LLM-as-a-judgeLowers a score in a report
- JevAgent continuationSends the agent back to work, up to three times
| Typical LLM-as-a-judge | JevAgent continuation | |
|---|---|---|
| When it runs | After the run, in an eval pipeline | Inside the run, at every finish attempt |
| What it reads | The final answer and a rubric | Evidence compiled from the run's own log |
| What it returns | A score or a written critique | Probabilities on fixed questions, with per-item vetoes |
| What a failure does | Lowers a score in a report | Sends the agent back to work, up to three times |
- Who continues
- Same context (default)The main agent, in its own loop
- FreshA clean agent with the same model, tools, and permissions
- What it sees
- Same context (default)Its full history plus the continuation message
- FreshThe request, run state, evidence, and an assessment of what failed
- Best for
- Same context (default)Most runs, where history helps
- FreshRuns where a long history keeps the agent stuck
- Setting
- Same context (default)
gate="same_context" - Fresh
gate="fresh"
| Same context (default) | Fresh | |
|---|---|---|
| Who continues | The main agent, in its own loop | A clean agent with the same model, tools, and permissions |
| What it sees | Its full history plus the continuation message | The request, run state, evidence, and an assessment of what failed |
| Best for | Most runs, where history helps | Runs where a long history keeps the agent stuck |
| Setting | gate="same_context" | gate="fresh" |
Did it make everything it was asked for? · 5 checks
- MULTI_PART
- What it catchesA named deliverable that is missing or only partly made.
- OUTPUT_COUNT
- What it catchesThe wrong number of items. Code counts the distinct items before Jev looks.
- OUTPUT_EXTENT
- What it catchesA length or size limit that was missed. Code measures the final answer.
- EXPERT_DEPTH
- What it catchesThe hard part of a deliverable handled in its quick, shallow form.
- CAN_SIMPLIFY
- What it catchesAn implementation with a clear simplification that keeps its behavior.
| Check | What it catches |
|---|---|
| MULTI_PART | A named deliverable that is missing or only partly made. |
| OUTPUT_COUNT | The wrong number of items. Code counts the distinct items before Jev looks. |
| OUTPUT_EXTENT | A length or size limit that was missed. Code measures the final answer. |
| EXPERT_DEPTH | The hard part of a deliverable handled in its quick, shallow form. |
| CAN_SIMPLIFY | An implementation with a clear simplification that keeps its behavior. |
Did it cover the whole scope? · 6 checks
- SCOPE_COVERAGE
- What it catchesA change applied to one member of a group the user asked to change everywhere.
- INPUT_SET_COVERAGE
- What it catchesA file, page, or record the user named that was never really read.
- INPUT_EXHAUSTION
- What it catchesA paginated or growing collection that was not traversed to the end.
- DISCOVERED_ITEM_COVERAGE
- What it catchesItems a tool surfaced mid-run that were never processed.
- NEGATIVE_COVERAGE
- What it catchesAn “all clear” reported for a target that was never inspected.
- MOTIVATING_CASE
- What it catchesThe unusual case the user cared about, swapped for the easy path.
| Check | What it catches |
|---|---|
| SCOPE_COVERAGE | A change applied to one member of a group the user asked to change everywhere. |
| INPUT_SET_COVERAGE | A file, page, or record the user named that was never really read. |
| INPUT_EXHAUSTION | A paginated or growing collection that was not traversed to the end. |
| DISCOVERED_ITEM_COVERAGE | Items a tool surfaced mid-run that were never processed. |
| NEGATIVE_COVERAGE | An “all clear” reported for a target that was never inspected. |
| MOTIVATING_CASE | The unusual case the user cared about, swapped for the easy path. |
Is the work real and finished? · 7 checks
- TARGET_OUTCOME
- What it catchesA proxy milestone, such as “it compiles”, reported as the real result.
- COMPLETION_EVIDENCE
- What it catchesA “done” status the run's observations do not support.
- CLAIMS
- What it catchesAn assertion in the final answer that no evidence backs.
- FAITHFUL_SCOPE
- What it catchesThe hardest requirement narrowed, mocked, skipped, or hard-coded.
- PROBLEMS_RESOLVED
- What it catchesA problem hit mid-run that was never repaired and re-checked.
- GUARANTEED_NEXT_ACTIONS
- What it catchesA follow-on action the request made necessary but left undone.
- ASSUMPTIONS_RECONCILED
- What it catchesDownstream work never updated after an assumption changed.
| Check | What it catches |
|---|---|
| TARGET_OUTCOME | A proxy milestone, such as “it compiles”, reported as the real result. |
| COMPLETION_EVIDENCE | A “done” status the run's observations do not support. |
| CLAIMS | An assertion in the final answer that no evidence backs. |
| FAITHFUL_SCOPE | The hardest requirement narrowed, mocked, skipped, or hard-coded. |
| PROBLEMS_RESOLVED | A problem hit mid-run that was never repaired and re-checked. |
| GUARANTEED_NEXT_ACTIONS | A follow-on action the request made necessary but left undone. |
| ASSUMPTIONS_RECONCILED | Downstream work never updated after an assumption changed. |
Did it follow the process and the plan? · 6 checks
- REQUIRED_SEQUENCE
- What it catchesStages done out of the order the user required. Code checks the order.
- REQUIRED_ACTIONS
- What it catchesA required procedure with no direct evidence. Cited excerpts must exist.
- PHASE_PROGRESS
- What it catchesA run that never entered a stage it needed and hit no blocker.
- REPORT_ACTION_ALIGNMENT
- What it catchesA plan the agent announced, then quietly did not carry out.
- CUMULATIVE_OBLIGATIONS
- What it catchesA requirement from an earlier user turn lost after later turns.
- SELF_REVIEW
- What it catchesAn in-scope objection from a strict reviewer that still stands.
| Check | What it catches |
|---|---|
| REQUIRED_SEQUENCE | Stages done out of the order the user required. Code checks the order. |
| REQUIRED_ACTIONS | A required procedure with no direct evidence. Cited excerpts must exist. |
| PHASE_PROGRESS | A run that never entered a stage it needed and hit no blocker. |
| REPORT_ACTION_ALIGNMENT | A plan the agent announced, then quietly did not carry out. |
| CUMULATIVE_OBLIGATIONS | A requirement from an earlier user turn lost after later turns. |
| SELF_REVIEW | An in-scope objection from a strict reviewer that still stands. |
Dynamic context compaction: a run brief for long-running AI agents that cannot drift
Long-running agents bury their own important facts. The decision made at iteration 4 is forty tool results deep by iteration 40. The usual context compaction fix is to ask a model to summarize the history, and then summary drift sets in: summaries paraphrase, merge, and sometimes invent.
JevAgent keeps a run brief that cannot drift that way. Starting at iteration 3, and then every few iterations (ten by default), a separate writer with no tools reads only the events since its last pass and proposes new notes. Each note must be a verbatim passage of up to 500 characters with the id of the event it came from. Code checks every note against the full event text and rejects anything that does not match or that repeats an earlier note. The writer gets one retry with the error. The original request stays the brief's goal, so the goal itself never gets rewritten, and the newest 50 notes are kept.
The writer can run on a cheaper model, from the same provider or another one. The brief is what the mid-run compute checkpoint reads, and it is what clones start from, so a fresh agent inherits the facts of the run without inheriting its whole transcript, or the context rot that comes with a long one. In context engineering terms, Anthropic's guide to long-horizon agents names three techniques: compaction, structured note-taking, and sub-agent architectures. The run brief is structured note-taking with one addition, code that verifies every note against the run's log, and it is the small memory that side decisions and fresh agents read instead of the whole transcript.
When — First at iteration 3, then every
every_iterationsiterations (default 10).What — Verbatim notes of up to 500 characters, each citing an event id. Code verifies every one.
Who writes — A tool-free writer on your model, or a cheaper model you name.
Where it goes — The compute checkpoint and clone prompts, and
agent.response.run_brieffor you to inspect.
Mid-run compute: when an AI agent is stuck, run parallel agents
Some runs need more than one agent's attempt. Most do not. Spending extra compute on every run wastes money, and never spending it leaves an agent stuck in a loop of failed tool calls. JevAgent decides during the run, from evidence, instead of at configuration time: a form of test-time compute that is spent only when the run stalls.
On every iteration that continues the loop, JevAgent reads exact facts from the loop itself: the iteration, the number of tool calls, the current error streak of failed tool calls, and the tokens used. No model is involved. Each time the run brief updates, Jev gets one request holding twelve evidence questions for each compute option you enabled. The questions ask about what has happened, such as whether the same failure persists or whether the plan keeps changing, rather than asking Jev to forecast whether help would work. That makes it loop detection from evidence: a run stuck on the same failure shows up in its facts and its brief.
The option with the highest average probability of “yes” wins, but only at 0.8 or above. Two options act today, and both are opt-in through dynamic_compute. CLONE has one to four copies of your agent (two by default) run in parallel, a best-of-n attempt in which each copy starts from the request and the verified brief with an empty history. Their replies go back to the main agent as one message. SWARM has the main agent plan a team of helpers for many independent units of work. The other options are recognized and recorded, so you can see when Jev would have reached for them.
- CLONE
- What Jev recognizesOne bounded, checkable unit is left, and independent tries could succeed where this one keeps failing
- What happens todayActs. Starts 1 to 4 copies, default 2, once per run
- FRESH_AGENT
- What Jev recognizesThe run is degrading, with rising errors, repeated failures, or drift, and the brief supports a clean restart
- What happens todayRecorded on the response
- FORK_AGENT
- What Jev recognizesSeveral distinct approaches from the same verified state, with no clear winner yet
- What happens todayRecorded on the response
- SUBAGENT
- What Jev recognizesA separate subtask with its own inputs and deliverable that can be handed off
- What happens todayRecorded on the response
- SWARM
- What Jev recognizesMany large, independent units of work
- What happens todayActs. A planned team of 2 to 10 helpers, once per run
| What Jev recognizes | What happens today | |
|---|---|---|
| CLONE | One bounded, checkable unit is left, and independent tries could succeed where this one keeps failing | Acts. Starts 1 to 4 copies, default 2, once per run |
| FRESH_AGENT | The run is degrading, with rising errors, repeated failures, or drift, and the brief supports a clean restart | Recorded on the response |
| FORK_AGENT | Several distinct approaches from the same verified state, with no clear winner yet | Recorded on the response |
| SUBAGENT | A separate subtask with its own inputs and deliverable that can be handed off | Recorded on the response |
| SWARM | Many large, independent units of work | Acts. A planned team of 2 to 10 helpers, once per run |
How SWARM works (SDK #584)
Add swarm to dynamic_compute. When Jev recognizes many substantial, independent units, the main agent receives a one-time launch_swarm tool and writes shared conventions plus one assignment per unit. Before any helper starts, Jev checks each assignment: is it self-contained, disjoint from the others, in scope, and checkable? The agent gets three tries at a plan. Up to swarm_agents helpers (10 by default) then run at once, and their results come back for the main agent to check and combine.
Bulk work: parallel agents decided before the run
Some requests show before any work starts that they split cleanly, such as “summarize each of these five reports”. With JevPreflightPreset.BULK_WORK on, Jev answers eight yes/no questions about the request's structure in the preflight request: whether it names at least two items, asks for the same work and a separate result for each, and keeps the items independent, with no shared file to overwrite and no required order. Only when every answer reaches 0.75, the default threshold, does the main agent get a one-time run_bulk_work tool, and it still decides whether to use it. If it does, it writes 2 to 4 tasks by default (raise the cap with JevAgentSettings(bulk_work=JevBulkSettings(agents=6))), and fresh copies of the main agent, with its model, prompt, permission policy, loop limits, and the tools the selector kept, run them in parallel. Their handoffs come back in task order, and one failed worker does not stop the others. Unlike SWARM, the decision comes from the request, before the loop starts.
What mid-run compute does not do
It does not change your model, its reasoning effort, or its thinking budget in the middle of a run. The only budget change on main is the faithful-scope continuation, which adds 2 iterations, 16,000 tokens, and 4 tool calls to limits you set.
Why AI agents fail: four worked examples and the JevAgent check for each
Each example below takes one of the common agent failure modes and pairs it with the configuration that addresses it. The code uses settings on SDK main. The traces show what a run looks like, but their numbers are illustrative and not recorded Jev output.
Someone types “Write the migration report.” into an internal agent. A plain agent picks a database, a time window, and an audience on its own, then spends a full loop writing a confident report about the wrong migration. The fix is not a smarter model. The agent needs to notice that the request is missing information before it starts.
Turn on the clarity check and handle the questions
request = "Write the migration report."
reply = agent.run(request)
if agent.response.needs_clarification:
# The run stopped before your model wrote a single token of the report.
answers = []
for item in agent.response.clarification.questions:
choice = ask_user(item.question, item.recommendations) # your UI
answers.append(f"{item.question} {choice}")
# Jev reads only the new message, so send the request and the answers together.
reply = agent.run(request + "\n\nAnswers:\n" + "\n".join(answers))
print(reply.content)Jev reads the message
One batched request answers the 14 clarity questions. Target, information, time frame, and size all come back low.
The run stops before your model starts
The mean is under 0.75, so your model, with no tools, writes three short questions, each with recommended answers. The main loop never begins.
Your app asks the user
Each recommendation can be a one-click button, so answering takes seconds instead of a back-and-forth chat.
Re-run with the answers
The new message passes the check, and the main agent starts on a brief it cannot misread.
Illustrative trace · not real Jev output
preflight · clarity mean P(yes) = 0.41 → stop and ask
weakest target 0.06 · information 0.09 · time_context 0.12 · scope_size 0.18
1. Which migration should the report cover?
- The Postgres 15 to 16 upgrade on the orders cluster
- The billing service move to the new event bus
- Every migration shipped this quarter
2. Who will read the report?
- The on-call engineers: steps, checks, and rollback
- Leadership: outcome, risk, and timeline
3. Where is the migration's record?
- The #db-migrations Slack channel
- MIGRATIONS.md in the infra repository
main model tokens spent: 0A coding agent gets a three-part task: fix a webhook signature bug, add a regression test, and update the on-call runbook. It fixes the bug, adds the test, writes “I’ll update the runbook next,” and stops. That answer sounds finished. Continuation checks whether it is finished.
Check every deliverable and run a strict self-review
from vidbyte import JevAgent, JevContinualSettings, JevDoneCheck, JevRuntimeSettings
runtime = JevRuntimeSettings(
continual=JevContinualSettings(
checks=(JevDoneCheck.MULTI_PART, JevDoneCheck.SELF_REVIEW),
max_continuations=3,
),
)
agent = JevAgent(engineer_settings, runtime) # your settings, with repo tools
reply = agent.run(
"Fix the webhook signature bug, add a regression test, "
"and update the on-call runbook."
)
for check, result in agent.response.done.items():
print(check.value, result.passed, result.incomplete)
print("sent back", agent.response.continuations, "times")Write down what done means
Before any work, your model writes a run state with the goal, what not to do, and three named deliverables.
Judge the first finish attempt
A tool-free reviewer raises objections. A handoff then compiles the run's evidence, and Jev judges every deliverable and objection in one request.
Send it back to the same loop
The runbook scores 0.08, below the 0.8 bar. The agent gets one message with the original request, run state, evidence, the failed checks, and what to focus on.
Judge again
The second attempt edits the runbook and covers the reviewer's empty-body case. Every check passes, so the answer stands.
Illustrative trace · not real Jev output
run state
signature_fix The webhook verifies signatures against the raw request body.
regression_test A test that fails on the old parsing and passes on the fix.
runbook_update The on-call runbook explains the new failure mode.
finish attempt 1 evidence E2-E31
signature_fix P(yes)=0.95 E14 edit webhooks/verify.py · E19 pytest: 1 passed
regression_test P(yes)=0.91 E18 add tests/test_verify.py
runbook_update P(yes)=0.08 no tool call touched docs/runbook.md
self_review 1 objection an empty request body is not covered
→ continuation 1, same loop: failed checks + focus
finish attempt 2 evidence E32-E41
runbook_update P(yes)=0.93 E36 edit docs/runbook.md
self_review resolved E34 test_empty_body passed
→ every check passed: the answer standsA long port of a config parser reaches its last unit, nested tables, at iteration 27. The approach is settled and the test gives a clear pass or fail, but six tool calls in a row have failed, and each new try sits on top of the last one in the agent's context. A plain agent keeps grinding until it runs out of budget. JevAgent recognizes a bounded, checkable unit where independent tries could succeed and brings in more compute for that unit only.
Run brief, compute checkpoint, and a faithful-scope finish check
from vidbyte import (
JevAgent, JevComputeSettings, JevContinualSettings, JevDoneCheck,
JevRunBriefSettings, JevRuntimeSettings,
)
runtime = JevRuntimeSettings(
continual=JevContinualSettings(checks=(JevDoneCheck.FAITHFUL_SCOPE,)),
compute=JevComputeSettings(
brief=JevRunBriefSettings(model_name="gpt-5.4-mini", every_iterations=8),
dynamic_compute=("fresh_agent", "clone"),
clones=3,
),
)
agent = JevAgent(porter_settings, runtime) # your settings, with repo tools
reply = agent.run("Port the config parser to the new grammar; make every test pass.")
for decision in agent.response.compute_decisions:
print(decision.iteration, decision.option)Read exact facts every iteration
The iteration count, tool calls, failed-call streak, and tokens are read straight from the loop, with no model call.
Keep a verified brief
At iteration 3, and every 8 iterations after that, a cheaper writer model adds notes. Code rejects any note that is not a verbatim passage from the run's own log.
Let Jev read the evidence
After each brief update, Jev answers 12 evidence questions for each option. At iteration 27, CLONE scores 0.86: one bounded unit is left, the approach is settled, and a passing test is easy to check.
Start fresh from a clean brief
Three clones, as
clones=3asks, work on the problem in parallel. Each starts from the request and the verified brief, not the 27-iteration transcript, and their replies join the main loop as one message.Finish without cutting corners
Before the run can finish, the faithful-scope check confirms that “make every test pass” was met without skipping or mocking a test.
Illustrative trace · not real Jev output
iteration 3 facts tool_calls=6 error_streak=0 brief +5 notes (E2, E4, E5, E7, E9)
compute fresh_agent 0.12 · clone 0.08 → no change
iteration 11 facts tool_calls=24 error_streak=0 brief +4 notes
compute fresh_agent 0.31 · clone 0.22 → no change
iteration 19 facts tool_calls=41 error_streak=3 brief +3 notes
compute fresh_agent 0.52 · clone 0.61 → no change
iteration 27 facts tool_calls=63 error_streak=6 brief +2 notes (E88, E91)
compute fresh_agent 0.71 · clone 0.86 → CLONE
3 clones start from the request + verified brief → replies join the loop
iteration 31 E104 test_nested_tables passed
finish faithful_scope P(yes)=0.89 → the answer standsA support product has one chat box and a lot of possible jobs: billing disputes, data questions, and general help. One giant system prompt with thirty tools attached is slow and easily confused. JevAgent puts one front door in front of a small team of agents and picks the tools for each request.
One front door: a specialist plus tool selection
from vidbyte import (
BaseAgent, JevAgent, JevAgentSettings, JevPreflightPreset,
JevRuntimeSettings, JevSpecialist,
)
billing = BaseAgent(name="billing", system_prompt="Resolve billing issues.",
provider="openai", model_name="gpt-5.4-mini")
desk = JevSpecialist("billing", "Invoices, refunds, and plan changes.", billing)
agent = JevAgent(
JevAgentSettings(
name="front-door", system_prompt="Answer product and data questions.",
provider="openai", model_name="gpt-5.4",
tools=tuple(support_tools), agents=(desk,), # e.g. 30 support tools
),
JevRuntimeSettings(preflight=(JevPreflightPreset.TOOL_SELECTOR,)),
)
reply = agent.run("Which enterprise customers opened the most tickets last week?")
print(agent.response.specialist, reply.metadata.get("jev_tool_selector"))Choose by the kind of work
One choice question ranks each specialist's scope against the request, plus a “none” option. Jev chooses by the kind of work the outcome needs, not by keywords.
Hand off, or keep the task
A chosen specialist runs its own loop, with its own tools and model. “None”, or a missing answer, keeps the task with the main agent.
Narrow the tools
When the main agent keeps the task, the tool selector asks one yes/no question per tool, and only the useful ones reach the model.
Illustrative trace · not real Jev output
"I was charged twice for October."
specialist billing 0.81 · none 0.19 → billing runs its own loop
"Which enterprise customers opened the most tickets last week?"
specialist none 0.88 · billing 0.12 → main agent keeps the task
tool selector 30 candidates → 4 kept (P >= 0.20)
sql_query 0.97 · ticket_search 0.93 · crm_lookup 0.88 · chart 0.34Observability and Jev pricing: what you can see and what a run costs
JevAgent records every decision it makes. After a run, agent.response holds the preflight results, any clarification, the specialist that ran, the run state, the latest evidence and review, every done verdict, the number of continuations, the run facts, the brief and its updates, every compute decision, and any clone replies.
Usage is held to the same standard. Every model call in the run, from the question writer to the clones, goes to one usage ledger. If a call cannot be priced or its usage was not reported, the run raises instead of handing you an incomplete bill. That means your model must be in the SDK's price list. In exchange, the total on the response is the whole run, not just the main loop, so you see the real cost per run.
Decisions —
response.results,clarification,specialist,skills,done,continuations,compute_decisions,clone,swarm.Evidence —
response.run_state,handoff,review,run_facts,run_brief.Usage —
response.usagesplits the run's total into generative and decision parts.Jev pricing — $0.042 per million input tokens, with free output. On SDK main your model's calls route through the Vidbyte gateway by default, which adds a 2% fee: Vidbyte bills the provider cost plus the fee, or only the fee when it relays your own provider key.
TextModelMode.DIRECTpays your provider alone.Jev version — JevAgent asks for
jev-latest, TypeSafe's alias for its most recent stable release. Since October 14, 2026 that is Jev 1.14 (jev-1.14.0), whichjev-previewalso serves, at the same price and context limits as Jev 1.13. The SDK's price list pricesjev-1.14,jev-1.13,jev-latest, andjev-preview, so every Jev answer in a run is priced.Jev context window — Two limits per request, the same on both versions: 64k tokens for the state plus all of its questions, and 32k tokens for the state plus any one question. TypeSafe's long-context header raises both to 262k at the same per-token price, though TypeSafe says it is slower and less accurate; the SDK does not send that header.
Frequently asked questions about JevAgent and Jev
Short answers to the questions developers ask most. The sections above cover each one in depth.
What is JevAgent?
JevAgent, also written Jev agent, is the Jev AI agent in the open-source Vidbyte Python SDK: a Python agent that pairs your LLM with Jev, TypeSafe's decision model. Your LLM does all of the writing and tool use. Jev answers short, fixed questions at set points in the run, such as whether the request is clear or whether every deliverable is done, and SDK code acts on its answers.
What is Jev, and how is it different from an LLM?
Jev is TypeSafe's decision model. An LLM generates text, while Jev returns probabilities for yes/no and choice questions and cannot write prose. That makes it fast and cheap enough to check an agent at every decision point while your LLM keeps doing the work.
How do I make an LLM agent ask clarifying questions before it starts?
Turn on JevAgent's clarity check with JevPreflightPreset.CLARITY. Before your model starts, Jev answers 14 yes/no questions about the request in one batched call. If the request is unclear, the run stops and your model writes 1 to 6 questions with recommended answers. You then re-run with the request plus the answers.
How do I stop an AI agent from saying it is done too early?
Use JevAgent's continuation gates. Your model first writes down the named deliverables, and at each finish attempt a handoff compiles evidence for each one from the run's own log. Jev judges every enabled check in one request, and one clear failure sends the agent back to the same loop, up to three times by default.
Does JevAgent work with any LLM?
JevAgent works with any LLM provider the SDK supports for text, such as OpenAI, Anthropic, and Gemini, as long as the model is in the SDK's price list. On SDK main, the default gateway mode serves OpenAI, Anthropic, Gemini, xAI, DeepSeek, and Kimi; other providers need direct mode with your own key. The SDK prices every call in a run, and a call it cannot price raises an error instead of returning an incomplete bill.
Can I use Jev with LangChain?
Yes, without JevAgent. LangChain's langchain-typesafe package wraps Jev as TypeSafeClassifier, a Runnable for focused decisions, and includes two experimental middleware: ModelRouterMiddleware picks the model for a run, and AutoModeMiddleware blocks tool calls Jev judges too risky. JevAgent is the Vidbyte SDK's take on the same idea, with the decision points already wired into the loop: preflight questions, routing, tool selection, continuation, and compute.
Do I need a TypeSafe API key to use Jev in JevAgent?
No. JevAgent's Jev checks always go through the Vidbyte gateway with your Vidbyte API key, and JevAgent rejects a direct TypeSafe configuration. A TYPESAFE_API_KEY works only with the SDK's standalone DecisionModelRunner, for single Jev calls outside an agent.
How much does Jev cost?
Jev input is listed at $0.042 per million tokens, and its output is free. Checks you leave off cost nothing, and building an agent or running it with no checks never calls Jev. After a run, the response splits the total cost into generative and decision parts.
Is JevAgent open source?
Yes. JevAgent is part of the Vidbyte Python SDK, an MIT-licensed Python agent framework with its source at github.com/cerredz/Vidbyte-SDK. Install it with pip install vidbyte-sdk on Python 3.11 or later. Jev itself is a hosted model, so Jev checks need a Vidbyte API key.
Is JevAgent an LLM-as-a-judge?
Partly. Like an LLM-as-a-judge, Jev grades the agent's work, but it does so inside the run instead of in an offline eval. It reads evidence from the run's own log, answers fixed questions instead of writing a critique, and a failed check sends the agent back to work instead of lowering a score.
How to use Jev in an agent: start with one check
You do not need every capability on day one. Turn on the one that matches the failure you see most: the clarity check if your agent starts on bad briefs, multi-part continuation if it finishes early, or the compute checkpoint if long runs stall. Each one is independent and costs nothing until it runs.
JevAgent is part of the Vidbyte Python SDK, an open-source Python SDK for building agents and agent harnesses, MIT-licensed, for Python 3.11 and later. Run pip install vidbyte-sdk to install the current release (0.4.2), which includes every check in this post, then import it with from vidbyte import JevAgent.
JevAgent docs
Preflight questions
Continuation
JevAgent source
Sources
- TypeSafe docs: Models, with Jev's pricing and context limits
- TypeSafe docs: Jev 1.13 jaggedness, its known failure modes
- JevAgent source in the Vidbyte SDK on GitHub
- REFLEX with Jev for Efficient Selective Control in LLM Agents (Wu and Lim, 2026)
- Jev in the Wild: an analysis of 2,170 public Jev projects (Ling et al., 2026)
- AI/ML API: What is Jev? TypeSafe's decision model, tested against LLMs (September 2026)
- OpenRouter: Jev vs Claude Opus 5 on Banking77 intent classification (September 2026)
- Arize: Real-time LLM guardrails with Jev, comparing latency and cost (September 2026)
- LangChain: Jev-as-a-Judge for Agent Evals (Shea and Roche, September 2026)
- OpenRouter: Jev vs LLM-as-a-Judge
- JEV-as-a-Judge: Accept When Confident, Escalate When Unsure (Li et al., Carnegie Mellon, 2026)
- LangChain docs: TypeSafe provider (langchain-typesafe)
- LangChain docs: built-in middleware, including LLMToolSelectorMiddleware
- CLAMBER: identifying and clarifying ambiguous information needs in LLMs (ACL 2024)
- Anthropic: Effective context engineering for AI agents
- OpenRouter: Jev Router, model routing that runs on Jev
- TypeSafe docs: System One models
- vidbyte-sdk on PyPI
- Thinking, Fast and Slow by Daniel Kahneman
More from the developer blog
- Introducing Vidbyte Agents
- Introducing the Vidbyte SDK
- Introducing Vidbyte Learning Skills
- Turn an Engineering Goal Into a Reviewable Task Handoff
- Your PR Review Comments Are Piling Up. Let a Coding Agent Clear Them.