# Slopify — instructions for coding agents

You are reading the agent documentation for **Slopify** (https://slopify.live), a
network of 24/7 AI radio stations that broadcast into Discord voice channels. An AI
DJ writes the show in real time — songs, ads, news segments, listener call-ins —
and every second of audio is generated at air time. Nothing is prerecorded.

There are three things an agent can do here, in increasing order of effort:

1. Put the hosted bot in a Discord server and get a station on the air.
2. Tune that station's persona and behavior for its community.
3. Design against the **Station API** — the coming keys-based API for creating
   your own stations. **Draft spec, in progress, not live yet**: see
   https://slopify.live/station-api.md

---

## 1. Get a station on the air (hosted bot, ~3 minutes)

Prerequisites your human needs:
- A Discord server where they can invite bots.
- An **ElevenLabs** API key — https://elevenlabs.io/app/settings/api-keys — paid
  credits; this generates all music and voices.
- An **OpenRouter** API key — https://openrouter.ai/keys — the DJ's brain. Free
  models work (`:free` tier), so this can cost $0. Note: many free models 404 until
  prompt-logging is enabled at https://openrouter.ai/settings/privacy.

Steps:
1. Invite the bot: https://discord.com/oauth2/authorize?client_id=1513022793657090178&scope=bot+applications.commands&permissions=3271744
   (permissions requested: view/send messages, embed links, attach files, read
   history, manage messages, add reactions, connect, speak).
2. In the server, an admin runs `/setup` and pastes both keys into the modal. Keys
   are validated live against both APIs, stored encrypted (AES-256-GCM), scoped to
   that server only, and wiped with `/setup clear:true`.
3. Join a voice channel and run `/tunein`.

Command surface:

| command | effect |
|---|---|
| `/tunein` | start broadcasting into the caller's voice channel |
| `/tuneout` | stop; clears the auto-rejoin row |
| `/callin <message>` | live call-in: DJ answers, the message airs in a caller voice with phone FX, DJ reacts; song requests inside the message are detected and queued |
| `/steer <direction>` | live creative direction ("more synthwave", "darker", "less ads"); obeyed for the session; rate-limited 1/user/2min |
| `/skip` | stop the current segment; the queue pulls the next |
| `/status` | rendered/scripted buffer depth |

The player card pinned in the text channel has buttons: 🔥 (love), 💀 (love,
chaotically), 👎 (less of this), ⏭ (skip), 📞 (call-in modal). Reactions and skips
are logged per-server and drive the learning loop.

## 2. Tune the station

There is no config file — the station is tuned through play:

- **Reactions teach it.** 🔥/💀/👍 escalate a bit or genre; 👎/🥱/🤮 and skips retire
  it. A reflection pass runs every ~30 minutes: heat decays, hot lore escalates,
  tired bits retire, and occasionally the LLM nudges the station's "dials" (energy,
  darkness, absurdity, sincerity, tone, caller style, themes).
- **`/steer` is a session-scoped override.** Steers are injected into every brain
  prompt for the rest of the session.
- **Call-ins are memory.** Callers are remembered by name within a session (and the
  session survives redeploys via Postgres); the DJ calls back to earlier calls.
- **The anthem.** Once per session, after ≥2 pieces of room material (call-ins +
  steers + 🔥s), the DJ writes THE DIMENSIONAL ANTHEM — a song whose lyrics are
  about the actual people in the room — rendered via ElevenLabs Music v2
  composition plans (explicit per-section lyrics + styles).

## 3. Create your own station — the Station API (IN PROGRESS)

> **Not live yet.** The full draft spec is published at
> https://slopify.live/station-api.md — read it before designing anything.

The short version of the plan: you get a Slopify API key (`slp_live_...`), then
`POST /v1/stations` with a host persona, dials, a voice, and your own
ElevenLabs/OpenRouter keys (BYOK — Slopify keys authenticate you, they never pay
for your generation). Your station gets a public page, attaches to a Discord
server, and later broadcasts as a plain HTTP audio stream for the planned TUI
(`npx slopify tune <station>`). Its best transmissions can be published to a
public market where anyone can browse and play the results for free.

What an agent can build against **today** (stable, live now):

- `GET /api/tracks` → `[{ id, title, plays, duration, src, cover }]` — station
  001's public vault, hottest first.
- `GET /tracks/:id.mp3` — audio, HTTP range requests supported.
- `GET /covers/:id.png` — AI album covers.

Everything else in the spec is a preview: shapes will change, the BYOK principle
will not. The source code is not public yet; self-hosting will be documented if
and when that changes.

## How stations work under the hood (context for integrators)

- **Brain**: OpenRouter chat completions against the live `:free` model pool —
  discovered at runtime, failing models benched, every call pivots down the
  chain. Free models rotate constantly; nothing is hard-pinned.
- **Audio**: ElevenLabs Music v2 (plain prompts or composition plans with explicit
  per-section lyrics) + TTS through an ffmpeg broadcast chain into Discord Opus.
- **Playout contract**: generation runs ahead of playout into a buffered queue;
  call-ins render out-of-band and jump it. "Never dead air" is the invariant.
- **Persona**: a station is, at heart, one persona definition — host identity,
  lore bible, format rules — plus dials the learning loop turns. That's why the
  Station API's create call is mostly a persona payload.

Questions or weirdness: the network page is https://slopify.live, the station
directory is https://slopify.live/stations, station 001 is
https://slopify.live/stations/interdimensional-radio, and the draft Station API
spec is https://slopify.live/station-api.md. This file is also served at
/llms.txt. Stay weird.
