jev-experiments

September 17, 2026 · View on GitHub

TypeSafe System One loops. Jev (or a labeled heuristic fallback) sees structured state and returns typed actions; Python owns execution. The canvas is a view — it never goes to the model.

ExperimentWhat it drivesInspector
Dino-JevReal chrome://dino/ in Chromiumhttp://127.0.0.1:8766
Krunker-JevLocal Krunker-style arenahttp://127.0.0.1:8765

Both stay in this repo. Develop them on separate branches; this tree keeps Krunker as-is.

Dino-Jev

A simpler parallel experiment: drive Chrome's offline dinosaur at chrome://dino/.

Same decomposition as Krunker-Jev, jev-ultrafast, and the Doom writeup:

  1. Code snapshots state. Runner.getInstance() exposes pose, speed, and obstacles. No screenshots to the model.
  2. One TypeSafe request per tick. Action, speculative jump/duck, and an urgency score, in parallel. See speculative fan-out.
  3. Code executes. Jump/duck gates live in dino_jev/policy.py. High pterodactyls cannot be jumped into; cacti cannot be ducked.
  4. The inspector is a view. The dino canvas stays in Chrome. Jev never sees those pixels.

Questions and thresholds are in dino_jev/questions.py.

HeadPrimitiveConsumed when
actionChoice (run / jump / duck)Always, unless confidence < 0.28 (keep last action)
jump_nowNoulGrounded, not intro, nearest clearance is ground or low
duck_nowNoulGrounded, not jumping, nearest clearance is mid
urgencyScoreDisplayed; does not move the body
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
cp .env.example .env   # or set JEV_API_KEY / TYPESAFE_API_KEY
python -m dino_jev probe-dino
python -m dino_jev play --policy heuristic --seconds 50
python -m dino_jev play --policy jev --seconds 20
python -m dino_jev serve

The command launches Chromium itself on chrome://dino/ in fullscreen arcade mode. You do not open a separate dino tab. Jump/duck run on that page (60fps Runner boxes). TypeSafe replies overlay the bottom-left corner so Chrome’s own score and the runner stay visible. The inspector at http://127.0.0.1:8766 is a decision log only — it does not screenshot the game.

  • Without a key the loop uses heuristic (in-page collision bot, clearly labeled).
  • With JEV_API_KEY or TYPESAFE_API_KEY set, it defaults to jev.
  • --speed-cap 9 (default) keeps maxSpeed just above pterodactyl spawn (8.5) so Jev's ~80ms tick can still commit. --speed-cap none is full runner acceleration.
  • --lead-frames 8 (default) is how many runner frames before a standing collision we jump, if the hop still clears. Lower (4–6) jumps later — better on clustered cacti, easier to clip the first one. Higher (10–14) jumps earlier — safer on singles, lands on wide clusters. Same constant in dino_jev/physics.py and dino_jev/static/bot.js. No in-game sliders.
  • The runner pauses on window blur and on resize. Dino-Jev patches those so it keeps going while the inspector or another window is focused.
  • Pass --windowed for a normal window.

Krunker-Jev

A TypeSafe System One loop in a Krunker-style arena. Jev (or a labeled heuristic fallback) sees structured combat state and returns typed actions; Python owns physics, vision, hitscan, and the inspector.

This is the Doom-shaped experiment from Introducing System One Models & Jev, not a live krunker.io aimbot.

Why a local arena, not krunker.io matches

Jev is text-only. The Doom demo fed structured game state, not frames. browser-use/jev-ultrafast uses the same idea for Google Flights: snapshot the page into an indexed element table, ask one TypeSafe request (operation + speculative targets), execute only the matching head.

A Krunker match is WebGL/canvas (game-overlay on top of three.js). There are no accessible buttons for WASD, look, or fire. A Flights-style DOM agent can, at best, click lobby chrome. Driving the match from hidden client transforms would be cheating, not a System One demo.

krunker.io lobby  →  DOM  →  jev-ultrafast could click Play (future)
krunker.io match  →  canvas/WebGL  →  Jev cannot see pixels
this repo         →  structured arena state  →  Jev chooses stance/move/aim/fire

python -m krunker_jev probe-krunker records what this environment can actually fetch from the live site.

Architecture

Same decomposition as jev-ultrafast and the Doom writeup:

  1. Code snapshots state. FOV, cover, ammo, health, bearings. No screenshots.
  2. One TypeSafe request per tick. Stance, move, speculative aim/fire/reload/jump, and a threat score, in parallel. See speculative fan-out.
  3. Code executes. Magazines, occlusion, and confidence gates live in krunker_jev/policy.py. Unused speculative answers cannot fire a shot.
  4. The inspector is a view. The canvas never goes to the model.

Questions and thresholds are in krunker_jev/questions.py so they can be reviewed in one place.

HeadPrimitiveConsumed when
stanceChoiceAlways, unless confidence < 0.32 (keep last stance)
moveChoiceAlways
aim_targetChoiceAlways; enemy ids are only offered when visible
fireNoulMag has ammo, not reloading, aim is a visible enemy
reloadNoulMag not full, not already reloading, not firing
jumpNoulProbability ≥ 0.80
threatScoreDisplayed; does not move the body

Run it

python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
cp .env.example .env   # or set JEV_API_KEY / TYPESAFE_API_KEY
python -m krunker_jev serve

Open http://127.0.0.1:8765

  • Without a key the inspector uses heuristic (same action space, clearly labeled).
  • With JEV_API_KEY or TYPESAFE_API_KEY set, it defaults to jev. Cursor runtime secrets named JEV_API_KEY are picked up at agent start, not on an already-running VM.

Headless:

python -m krunker_jev play --policy heuristic --ticks 80
python -m krunker_jev play --policy jev --scenario duel --ticks 40
python -m krunker_jev probe-krunker
pytest

What to try next

  • Point a jev-ultrafast agent at the Krunker lobby only (Play, mode, region). Stop before pointer-lock.
  • If TypeSafe adds vision, swap the observation for a caption of the HUD, still keeping hitscan in code.
  • Custom Krunker maps / KrunkScript can expose HUD text; still do not read other players' hidden transforms.