Dispatch
What the AI DJ knows when it opens the mic
Every link the DJ speaks is assembled from a small, carefully rationed bundle of context — the time, the weather, the last three tracks, and one rule: never talk longer than the intro.
Radio DJs have always worked from a stack of index cards: the log, the liners, the weather wire, a note from the program director. SUB/WAVE's DJ is no different — it just reads its cards a few hundred milliseconds before the red light comes on. This dispatch is about what's on those cards, and why so much of building an AI DJ is deciding what it doesn't get to know.
The context bundle
When a track ends, the controller assembles a prompt for the DJ. The temptation is to shovel everything in — the whole library, the full play history, every listener request since boot. That produces a DJ who rambles like a conspiracy theorist with a corkboard. Instead, the bundle is rationed:
| Card | Contents | Budget |
|---|---|---|
| Station clock | Local time, daypart, show name | ~40 tokens |
| Weather wire | Current conditions, one-line forecast | ~60 tokens |
| The log | Last 3 tracks with artist and year | ~120 tokens |
| Up next | The track it must introduce | ~50 tokens |
| Listener wire | Pending requests, if any | ~150 tokens |
| Persona sheet | Voice, quirks, catchphrases | ~400 tokens |
Everything else — the biography of the artist, the history of the label, the DJ's opinions about genre — comes from the model's own weights. That's the trick: the context sets the scene, the weights provide the knowledge, and the persona sheet decides the voice.
The shape of a link
The DJ's output is structured, not freeform. It returns a small JSON envelope the controller can act on:
{
"speech": "Twenty-two minutes past midnight, and that was Alice Coltrane — here's one that answers it.",
"mood": "late-night",
"duck_music": true,
"max_seconds": 12
}The max_seconds field is the most important line in the schema. A radio link that outstays the intro of the next song is a crime in any decade, so the controller treats the DJ's own estimate as a promise: if the rendered speech runs long, it gets cut at the fade and the DJ is told about it in the next bundle.
Teaching restraint
The persona sheet carries the rule in plain language:
export const midnight = {
name: 'Marlowe',
voice: 'low, unhurried, slightly amused',
rules: [
'Never speak over a cold open.',
'One thought per link. If you have two, save one.',
'The music is the show. You are the margin note.',
],
};The music is the show. You are the margin note.
That last rule does more work than any temperature setting. Models pattern-match on role descriptions, and "margin note" produces measurably shorter, drier, better links than "radio host" — which tends to summon the ghost of morning-zoo radio, air horns and all.
What it deliberately doesn't know
The DJ is not told listener counts. It's not told which tracks get skipped on other platforms, because there is no skip. It's not told what's trending. A radio station that watches its own numbers between every song starts hedging — and hedging is the one thing a broadsheet, or a broadcast, can't survive.
The DJ knows the time, the weather, the last song, and the next one. On most nights, that turns out to be exactly enough.