Not a music generator. It plays real songs and performs them with real DJ moves: scratches, loop rolls, spinbacks, crossfader chops. Every move is a tool call, decided live by Jev in about 150 milliseconds.
Coding agents get tools to read and edit files. This one gets tools to work the decks. A fast model answers one typed question per phrase, and the engine turns the answer into sound on the next downbeat.
Demucs splits each song into drums, bass, vocals and other. beat-this finds every beat and downbeat. Whisper finds the hook and the exact word to scratch.
Every couple of bars, one call with four typed questions: move, next song,
scratch style, hype. Answers come back with probabilities in ~150 ms.
A bar-by-bar engine: beat-locked time-stretch, key shifting, a scratch synth that models the platter and crossfader, EQ kills, filters, echo, reverb.
Every platter wobble, knob turn and fingertip in the video comes from what the engine actually did, recorded 30 times a second.
Code decides which moves are legal right now (phrase position, what just happened, what's playing). Jev picks one. If the answer comes back later than the two-bar window, the DJ misses the move.
deck.scratch_in(word, style)Scratch the next song's hook over the beat, then slam it in on the 1.
mixer.crossfader_chops()Flip between both decks every half beat, landing on the new hook.
deck.roll(1 → 1/8)A loop roll that shrinks with a rising filter and noise, into the drop.
deck.spinback()Rewind the record backwards, then drop the next song.
deck.brake()Slow the platter to a stop, like cutting power to the turntable.
fx.echo_out()Throw the last beat into a tempo-synced echo and cut it clean.
mixer.drop_gap()One beat of silence, then the next song hits with a sub boom.
deck.scratch_fill(style)A flashy scratch on the current hook to close a phrase.
mixer.filter_dip() · fx.echo_throw()Small accents inside a phrase, or ride: let it play.
Any model can sit at the decks. LLMs are smart but slow: at ~1 s a decision, they sometimes miss the window. Jev is built for exactly this kind of fast, narrow call.
A native, real-time version: two decks in Liquid Glass, Jev deciding every move live as the music plays. Load your own files, your Music library, Creative Commons tracks, or find a song by name or Spotify link.
macOS 26 or later, Apple Silicon or Intel. 2 MB. Nothing else to install: no API key, no Homebrew. Jev works out of the box, and the song finder sets itself up on first launch.
First launch: the app isn't notarized yet, so right-click Decks → Open → Open. You only need to do this once.
# or build it from source $ brew install xcodegen $ git clone https://github.com/yask123/ai-dj $ cd ai-dj/mac && xcodegen $ open Decks.xcodeproj # ⌘R
# macOS or Linux, Python 3.12 $ git clone https://github.com/yask123/ai-dj && cd ai-dj $ brew install ffmpeg rubberband yt-dlp $ uv venv --python 3.12 .venv $ uv pip install -r requirements.txt $ echo "sk-or-…" > .openrouter_key $ .venv/bin/python server.py # → localhost:8765 · pick two songs, pick a brain, drop it
One OpenRouter key covers Jev (typesafe/jev-1.13) and every
LLM you want to race it against. A set costs a fraction of a cent.
First-time songs take ~45 s on an Apple Silicon Mac: download, stems, beat grid, hook detection. After that they're cached and a new set takes seconds.
The live booth (/dj/booth) is the same app, running on my Mac. It's open when the Mac is awake.