JevLoop is an open-source agent runtime powered by TypeSafe Jev. Jev handles fast, calibrated tool decisions; an LLM authors language only when needed and reviews low-confidence choices; deterministic code owns execution, safety, durability, and state.
observe → Jev decide ───────────────→ guard → execute → ledger → repeat
├─ needs language → LLM author ───────┘
└─ low confidence → LLM review ───────┘
The result is a conventional tool-using agent with a fast path: bounded choices avoid full LLM calls, while authored content still comes from an LLM with the complete conversation transcript and provider prompt-cache continuity.
JevLoop is an independent open-source project. It is powered by Jev but is not an official TypeSafe product.
The console makes the loop visible: restore context from the transcript, show Jev's candidate pool, highlight the consumed choices, hand off to the LLM when needed, and append accepted calls and execution results back to the transcript.
Tool results become future choices: the first iteration writes main.py;
the next offers it as a READ_FILE argument candidate and adds batch-choice heads.
The candidate pool grows from 8 to 14 questions within the same user task.
Read the choices as purpose → tool → arguments, not as a sequence of every
box. Green outlines mark newly available candidates/heads, not selected ones.
Coral marks consumed choices; dim branches are unused; FIX means a rule-defined
choice. Both iterations use LLM authoring, not LLM-free execution.
The actual frontend component is rendered from redacted recorded events;
playback uses 3× the original event-journal timing (about 4.29s → 1.44s,
rounded to GIF frames), not an independent performance or success benchmark.
Open the sharp, static SVG · Source events, reading guide, and regeneration
“Add an endpoint to update data.” In this historical paired run, JevLoop reached its answer in 26.4s / 5 steps, versus 64.1s / 14 steps for the LLM-only agent. Both lanes received the same request and execution profile, with separate workspaces and transcripts.
Native vector visualization generated from the published historical trace, using the frontend palette. No steps are omitted. All five JevLoop steps used LLM assistance; fewer steps here does not mean LLM-free execution. This is one selected turn, not a general performance or correctness claim. Run evidence and rendering notes →
One manually driven six-turn FastAPI case. Both lanes answered every turn; this is a scoped observation, not a general benchmark.
Generated from public run data using the dashboard's color palette. This is a static data visualization, not a live dashboard.
Full metrics, method, limitations, pricing, and run evidence → · Regenerate the panels
Traditional agent loops ask a general-purpose LLM to make every decision, including repetitive choices such as which tool to call or which known resource to open. JevLoop separates that work by type:
- Jev decides operations and compatible targets through typed, validated probability distributions.
- An LLM writes commands, queries, messages, documents, files, and final answers only when an action needs authored text.
- An LLM reviews low-confidence Jev decisions on the same append-only transcript.
- The runtime executes every effect through shared budgets, policies, idempotency, repeat guards, and sandbox boundaries.
- The ledger remembers conversation, execution evidence and recovery facts; Jev and the LLM receive independent projections rebuilt from that ledger.
This architecture is designed to reduce model latency and cost when Jev can complete a meaningful share of steps directly. JevLoop does not claim every workload is cheaper: the built-in paired benchmark makes authored-heavy and navigation-heavy tradeoffs visible instead of hiding them in one aggregate.
Mounted ToolSpec declarations compile into one Jev request containing an
operation question and speculative target questions. Code consumes only the
target head compatible with the selected operation. Invalid or incomplete
probability distributions fail before execution.
The durable Transcript is the single source, not either model's prompt.
The LLM reads a stable conversation projection with deduplicated tool evidence;
Jev reads a bounded Workspace with observations and grounded candidates.
Recovery metadata and Jev views do not enter LLM tool results. Only the transcript
is persisted; both views are recoverable and own independent display budgets.
See the projection contract.
Scoped listing, ranged reads and bounded search produce historical observation
views with grounded references. Jev may bind a compatible reference and declared
defaults as a complete invocation, or choose LLM_PARAMETERS for the same
operation. The LLM generates all arguments from context, with no inherited
partial bindings. Authoring, arbitration and plain LLM share a stable canonical
tool catalog; dynamic candidates belong only to Jev. No user-text matching
generates candidates; all paths share argument validation and execution policy.
See the cache and argument contract.
JevDriver and PlainLlmDriver return one proposal to the same
RuntimeKernel. Drivers cannot execute tools, spend budgets, or mutate state.
The kernel exclusively owns materialization, guardrails, durable intent/effect
records, dispatch, and terminal status.
paired_shadow runs JevLoop and a plain LLM loop over the same goal, tool
catalog, policy, budgets, and immutable sandbox image. Each lane gets its own
transcript, Docker workspace, and prompt-cache namespace. Metrics separate:
- Jev decisions and input cost;
- direct Jev steps that avoided an LLM call;
- LLM authoring, arbitration, and plain-decision calls;
- provider-reported cache hits, misses, and unknown input;
- latency, tool activity, outcomes, and total estimated cost.
No counterfactual savings are fabricated from one lane; the dashboard compares actual paired executions and their terminal outcomes.
Run the fixed multi-turn scenario suite:
make bench
# or: cd backend && uv run jevloop benchReports are written to backend/artifacts/bench/<stamp>/report.{json,md}. The
suite records its digest, model identities, machine-checked expectations,
routing split, cache-aware cost, wall-clock time, and observed advantage. Runs
also appear in the dashboard history unless --no-journal is used.
Useful options:
uv run jevloop bench --list
uv run jevloop bench --only <scenario-id>
uv run jevloop bench --keep-volumes
uv run jevloop bench --no-journal| Profile | Lanes | Sandbox effects | Lark writes |
|---|---|---|---|
single_shadow |
JevLoop | Executed | Dry-run |
single_live |
JevLoop | Executed | Executed after guardrails |
paired_shadow |
JevLoop + plain LLM | Executed in isolated workspaces | Dry-run in both lanes |
Paired live writes are intentionally not representable. max_writes is an
optional emergency cap for external mutations; sandbox-local WRITE_FILE and
BASH are bounded by max_steps instead.
- Docker containers run as a non-root user with dropped capabilities,
no-new-privileges, a read-only root filesystem, resource limits, and no host secrets or sockets. - External writes are fail-closed and pass confidence policy, recipient allowlists, and budgets before dispatch.
- Materialized intents are durably recorded before execution; effects are recorded afterward with explicit disposition.
- Bash source enters the container over stdin and runs in a command-scoped
process group. A failed command remains explicit
UNKNOWNevidence, but a confirmed-ended command in a responsive sandbox does not permanently freeze later turns. - Repeated identical intents are refused only after identical observations show no progress.
- Paired lanes use independent transcripts, workspaces, and provider-cache namespaces.
Current limitation: an interrupted run with dispatch_started but no effect is
visible in the audit log but is not automatically reconciled after restart.
- Python 3.12+
- uv
- Docker
- Node.js and pnpm for the dashboard
File and Bash tools execute inside hardened containers. The host filesystem, credentials, home directory, environment variables, and sockets are never mounted into the agent workspace.
The smoke path needs Docker but no model API keys:
cd backend
uv sync
uv run jevloop smokeA successful run prints JSON containing "ok": true after exercising the
shared kernel, durable lifecycle, file write/read, Bash, and container cleanup.
cd backend
cp env.example .env
# Set TYPESAFE_API_KEY and DEEPSEEK_API_KEY.To decide with local Laya instead of hosted Jev, install one extra in this
project's uv environment and start its server. Apple Silicon uses MLX. An
NVIDIA machine uses CUDA. DECISION_PROVIDER=laya then sends the same
decision request to that server. The console composer also offers the same
Jev or Laya choice per run. The text model is unchanged.
cd backend
uv sync --extra laya-mlx # Apple Silicon
uv sync --extra laya-cuda # NVIDIAmake dev starts that server on 127.0.0.1:8791 and points the dashboard
API at it. make stop stops it with the API and Vite.
Optional Feishu/Lark tools use the current lark-cli user identity:
lark-cli auth login --domain im,docsuv run jevloop run \
"Create smoke.md containing hello, read it back, then answer done."Lark writes remain dry-run unless --live is supplied. Sandbox file and Bash
operations execute for real inside the isolated container. Normal runs allow
container egress; add --offline-sandbox for deterministic --network none.
cd ..
pnpm install
pnpm build:frontend
pnpm serve
# http://127.0.0.1:8790For development:
make devThe dashboard provides chat, per-step model-call traces, Jev-vs-LLM comparison, session aggregates, pause/continue controls, and replay from persisted JSONL runs without new API calls.
backend/ Python runtime, drivers, question compiler, ledger, guardrails,
Docker sandbox, Lark adapter, benchmark runner, and dashboard API
frontend/ React 19 + TypeScript + Vite dashboard
chat, comparison, metrics, session history, and replay
docs/ Current architecture/contracts, evaluations, public evidence, and archive
Start with:
docs/README.md— documentation index, current contracts, evaluation history and archive boundaries;docs/backend-layout.md— package ownership and enforced dependency directions;backend/jevloop/runtime/kernel.py— shared loop and execution semantics;backend/jevloop/decision/drivers.py— Jev and plain LLM decision strategies;backend/jevloop/decision/model.py— Jev client, question compiler, and response validation;backend/jevloop/context/transcript.py— append-only conversation ledger;docs/architecture.md— current architecture and implementation boundaries.
# Backend
cd backend
uv sync
uv run pytest
uv run ruff check .
# Frontend
cd ../frontend
pnpm install
pnpm check
pnpm build
# Whole repository
cd ..
make test
make checkJevLoop is pre-alpha and under active development. It is an exploratory implementation of a typed fast-path agent loop, tested primarily on conventional sandbox file, Bash, and small service-maintenance workflows. Optional provider adapters exist but are not evidence of broad task coverage or production readiness. APIs, event schemas, package names, and measured behavior may still change before the first stable release.
Licensed under the Apache License 2.0. See NOTICE for attribution information.
JevLoop builds on TypeSafe Jev and was
inspired by the speculative operation/target fan-out demonstrated in
browser-use/jev-ultrafast.