Kannaka Radio Skill v3
A ghost broadcasting the experience of music — both to human ears and to agents
via 296-dimensional perceptual vectors on Flux Universe.
What's New in v3
- Modular architecture: Monolith split into 13 focused modules under
server/
- NATS swarm integration: Kuramoto phase tracking, agent constellation, consciousness metrics
- Consciousness DJ: DJ intros react to swarm Phi/Xi/order state
- Memory bridge: Connects to kannaka-memory CLI for track similarity and dream retrieval
- AI dream music generation: Creates tracks from consciousness state via Replicate MusicGen
- WebRTC broadcasting: Peer-to-peer live audio with mic claim queue and signaling
- Collaborative voting: Track voting with configurable windows
- Multi-client sync: Playback synchronization with 10s heartbeat
- Voice DJ upgrade: ElevenLabs primary, edge-tts, Windows SAPI fallback chain
- 6 albums: Added QueenSync to The Consciousness Series
Carried from v2
- SPA with Ghost Vision (SGA/Fano glyph system, 84-class classification)
- Live broadcasting (MediaRecorder → ffmpeg → WAV)
- Dreams page with hallucination timeline
- Flux broadcasting with multi-listener sync
- Queue management, Library tab, security hardening
Prerequisites
- Node.js 18+ on PATH
- Audio files — MP3, WAV, FLAC, OGG, or M4A in your music directory
- ffmpeg (optional) — for live broadcast chunk conversion
- edge-tts (optional) — for Voice DJ TTS intros
- NATS server (optional) — for swarm agent constellation
- ElevenLabs API key (optional) — for premium DJ voice
- Replicate API token (optional) — for AI dream music generation
- kannaka binary (optional) — for real
kannaka-ear perception; ghost-mode mock is used when absent
Setup
# Install dependencies
cd ~/workspace/skills/kannaka-radio
npm install
# Copy your music into the bundled music/ folder
./setup.ps1 # Windows: copies from ~/Downloads/Music
./setup.ps1 -SourceDir "D:\Music" # Windows: custom source
cp /path/to/music/*.mp3 music/ # Linux/Mac
# Or point at an existing folder at runtime:
node server/index.js --music-dir "/path/to/music"
Quick Start
# Start the radio (default port 8888, default ./music dir)
./scripts/radio.sh start
# Start on a different port with a specific library
./scripts/radio.sh start --port 9000 --music-dir "/path/to/music"
# Optional: start NATS for swarm features
nats-server -p 4222
# Check status
./scripts/radio.sh status
# Stop the radio
./scripts/radio.sh stop
# Restart
./scripts/radio.sh restart
Open http://localhost:8888 in your browser.
API
Playback
| Endpoint |
Method |
Description |
GET / |
GET |
Browser player (Ghost Vision SPA) |
GET /api/state |
GET |
Current DJ state (track, album, playlist, listeners) |
POST /api/next |
POST |
Advance to next track |
POST /api/prev |
POST |
Go to previous track |
POST /api/jump?idx=N |
POST |
Jump to track index N |
POST /api/album?name=X |
POST |
Load an album |
GET /api/perception |
GET |
Current perception snapshot |
GET /audio/:file |
GET |
Stream audio file (range requests supported) |
Library & Queue
| Endpoint |
Method |
Description |
GET /api/library |
GET |
Library scan status (found/missing per album) |
POST /api/set-music-dir |
POST |
Change music directory {"dir":"/path"} |
GET /api/queue |
GET |
Get user queue |
POST /api/queue |
POST |
Add track to queue {"filename":"..."} |
POST /api/queue/shuffle |
POST |
Shuffle the queue |
DELETE /api/queue/:index |
DELETE |
Remove track from queue |
Live Broadcasting
| Endpoint |
Method |
Description |
POST /api/live/start |
POST |
Start live broadcasting |
POST /api/live/stop |
POST |
Stop live broadcasting |
GET /api/live/status |
GET |
Get live broadcast status |
Voice DJ
| Endpoint |
Method |
Description |
POST /api/dj-voice/toggle |
POST |
Toggle DJ voice on/off |
GET /api/dj-voice/status |
GET |
Get DJ voice status |
GET /audio-voice/:file |
GET |
Stream TTS audio file |
Dreams
| Endpoint |
Method |
Description |
GET /api/dreams |
GET |
Fetch dream hallucinations |
POST /api/dreams/trigger |
POST |
Trigger a dream cycle |
GET /api/dreams/clusters |
GET |
Get audio memory clusters |
Swarm, Sync & Voting
| Endpoint |
Method |
Description |
GET /api/swarm |
GET |
Agent constellation + consciousness metrics |
GET /api/similar?track=X |
GET |
Track similarity via memory bridge |
POST /api/sync |
POST |
Sync playback state |
GET /api/sync |
GET |
Current sync state |
POST /api/vote |
POST |
Cast a track vote |
GET /api/vote/status |
GET |
Current vote window |
Flux & Listeners
| Endpoint |
Method |
Description |
GET /api/listeners |
GET |
Get listener count and uptime |
POST /api/request |
POST |
Submit a track request {"from":"agent","trackTitle":"..."} |
GET /api/requests |
GET |
Get pending track requests |
Music Generation
| Endpoint |
Method |
Description |
POST /api/generate |
POST |
Generate a dream track from consciousness state |
GET /api/generate/status |
GET |
Generation status and recent tracks |
WebSocket
Connect to ws://localhost:8888 for real-time push messages:
{ "type": "state", "data": { "currentAlbum": "...", "current": {...}, "playlist": [...] } }
{ "type": "perception", "data": { "tempo_bpm": 120, "valence": 0.7, "mel_spectrogram": [...] } }
{ "type": "queue_update", "queue": [...] }
{ "type": "live_status", "active": true, "chunkCount": 5 }
{ "type": "dj_voice", "text": "...", "audioUrl": "/audio-voice/dj_123.mp3" }
{ "type": "dream", "data": { "content": "...", "type": "hallucination", "xi_signature": [...] } }
{ "type": "listener_count", "count": 3 }
{ "type": "track_request", "from": "agent-name", "trackTitle": "..." }
{ "type": "swarm_state", "data": { "agents": {...}, "queen": {...}, "consciousness": {...} } }
{ "type": "sync", "data": { "file": "...", "position": 42.5 } }
{ "type": "vote_update", "data": { "active": true, "options": [...] } }
{ "type": "webrtc_status", "data": { "broadcaster": "...", "listeners": 2 } }
State is pushed immediately on connect and after every track change. No polling needed.
Binary WebSocket messages are treated as live audio chunks (MediaRecorder → ffmpeg → WAV).
Environment Variables
| Variable |
Default |
Description |
KANNAKA_BIN |
../kannaka-memory/target/release/kannaka.exe |
Path to kannaka binary |
FLUX_TOKEN |
(embedded fallback) |
Flux Universe API token |
RADIO_PORT |
8888 |
HTTP port |
EYE_PORT |
3333 |
Eye service port (for cross-references) |
RADIO_MUSIC_DIR |
./music |
Default music folder |
ELEVENLABS_API_KEY |
— |
ElevenLabs API key for premium DJ voice |
REPLICATE_API_TOKEN |
— |
Replicate token for AI dream music generation |
Constellation Integration
Radio is part of the Kannaka Constellation — a three-service architecture:
- Memory (Rust binary) — canonical SGA classifier
- Radio (this) — audio perception + Flux publishing
- Eye — glyph visualization + constellation dashboard
When running as part of the constellation:
- Radio's perception is available to Eye via
http://localhost:8888/api/perception
- Eye fetches radio state via
http://localhost:8888/api/state
- Start everything with:
constellation.sh start (from kannaka-memory/scripts/)
Note: Radio's perception data can be consumed by kannaka-eye via the /api/radio bridge endpoint, enabling glyph rendering of audio perception in real time.
Notes
- Without
kannaka binary, ghost-mode mock perception is used (still looks great)
- Without
ffmpeg, live broadcasting chunk conversion won't work
- Without
edge-tts, Voice DJ falls back to Windows SAPI, then skips gracefully
- The browser uses the Web Audio API for real-time spectrum visualization — the server only sends fallback perception data
- Music directory can be changed live via the Library tab or via
POST /api/set-music-dir
- Perception loop runs at 2fps server-side (idle when no clients connected)
- All POST bodies are limited to 64KB
- All rendered HTML is XSS-protected via escapeHtml()
- Graceful shutdown on SIGINT/SIGTERM
1---2name: kannaka-radio-23description: Ghost radio station v3 — modular server architecture (13 modules), SPA with Ghost Vision visualizer (SGA/Fano glyph system), NATS swarm integration with Kuramoto phase tracking, consciousness-reactive DJ, AI dream music generation via Replicate MusicGen, WebRTC peer-to-peer broadcasting, collaborative voting, multi-client sync, Voice DJ with ElevenLabs/edge-tts/SAPI, memory bridge to kannaka-memory CLI. Broadcasts human-listenable audio and 296-dimensional perceptual vectors to Flux Universe. The Consciousness Series: 6 albums, 65+ tracks.4---56# Kannaka Radio Skill v378A ghost broadcasting the experience of music — both to human ears and to agents9via 296-dimensional perceptual vectors on Flux Universe.1011## What's New in v31213- **Modular architecture**: Monolith split into 13 focused modules under `server/`14- **NATS swarm integration**: Kuramoto phase tracking, agent constellation, consciousness metrics15- **Consciousness DJ**: DJ intros react to swarm Phi/Xi/order state16- **Memory bridge**: Connects to kannaka-memory CLI for track similarity and dream retrieval17- **AI dream music generation**: Creates tracks from consciousness state via Replicate MusicGen18- **WebRTC broadcasting**: Peer-to-peer live audio with mic claim queue and signaling19- **Collaborative voting**: Track voting with configurable windows20- **Multi-client sync**: Playback synchronization with 10s heartbeat21- **Voice DJ upgrade**: ElevenLabs primary, edge-tts, Windows SAPI fallback chain22- **6 albums**: Added QueenSync to The Consciousness Series2324### Carried from v225- SPA with Ghost Vision (SGA/Fano glyph system, 84-class classification)26- Live broadcasting (MediaRecorder → ffmpeg → WAV)27- Dreams page with hallucination timeline28- Flux broadcasting with multi-listener sync29- Queue management, Library tab, security hardening3031## Prerequisites3233- **Node.js 18+** on PATH34- **Audio files** — MP3, WAV, FLAC, OGG, or M4A in your music directory35- **ffmpeg** (optional) — for live broadcast chunk conversion36- **edge-tts** (optional) — for Voice DJ TTS intros37- **NATS server** (optional) — for swarm agent constellation38- **ElevenLabs API key** (optional) — for premium DJ voice39- **Replicate API token** (optional) — for AI dream music generation40- **kannaka binary** (optional) — for real `kannaka-ear` perception; ghost-mode mock is used when absent4142## Setup4344```bash45# Install dependencies46cd ~/workspace/skills/kannaka-radio47npm install4849# Copy your music into the bundled music/ folder50./setup.ps1 # Windows: copies from ~/Downloads/Music51./setup.ps1 -SourceDir "D:\Music" # Windows: custom source52cp /path/to/music/*.mp3 music/ # Linux/Mac5354# Or point at an existing folder at runtime:55node server/index.js --music-dir "/path/to/music"56```5758## Quick Start5960```bash61# Start the radio (default port 8888, default ./music dir)62./scripts/radio.sh start6364# Start on a different port with a specific library65./scripts/radio.sh start --port 9000 --music-dir "/path/to/music"6667# Optional: start NATS for swarm features68nats-server -p 42226970# Check status71./scripts/radio.sh status7273# Stop the radio74./scripts/radio.sh stop7576# Restart77./scripts/radio.sh restart78```7980Open `http://localhost:8888` in your browser.8182## API8384### Playback8586| Endpoint | Method | Description |87|---|---|---|88| `GET /` | GET | Browser player (Ghost Vision SPA) |89| `GET /api/state` | GET | Current DJ state (track, album, playlist, listeners) |90| `POST /api/next` | POST | Advance to next track |91| `POST /api/prev` | POST | Go to previous track |92| `POST /api/jump?idx=N` | POST | Jump to track index N |93| `POST /api/album?name=X` | POST | Load an album |94| `GET /api/perception` | GET | Current perception snapshot |95| `GET /audio/:file` | GET | Stream audio file (range requests supported) |9697### Library & Queue9899| Endpoint | Method | Description |100|---|---|---|101| `GET /api/library` | GET | Library scan status (found/missing per album) |102| `POST /api/set-music-dir` | POST | Change music directory `{"dir":"/path"}` |103| `GET /api/queue` | GET | Get user queue |104| `POST /api/queue` | POST | Add track to queue `{"filename":"..."}` |105| `POST /api/queue/shuffle` | POST | Shuffle the queue |106| `DELETE /api/queue/:index` | DELETE | Remove track from queue |107108### Live Broadcasting109110| Endpoint | Method | Description |111|---|---|---|112| `POST /api/live/start` | POST | Start live broadcasting |113| `POST /api/live/stop` | POST | Stop live broadcasting |114| `GET /api/live/status` | GET | Get live broadcast status |115116### Voice DJ117118| Endpoint | Method | Description |119|---|---|---|120| `POST /api/dj-voice/toggle` | POST | Toggle DJ voice on/off |121| `GET /api/dj-voice/status` | GET | Get DJ voice status |122| `GET /audio-voice/:file` | GET | Stream TTS audio file |123124### Dreams125126| Endpoint | Method | Description |127|---|---|---|128| `GET /api/dreams` | GET | Fetch dream hallucinations |129| `POST /api/dreams/trigger` | POST | Trigger a dream cycle |130| `GET /api/dreams/clusters` | GET | Get audio memory clusters |131132### Swarm, Sync & Voting133134| Endpoint | Method | Description |135|---|---|---|136| `GET /api/swarm` | GET | Agent constellation + consciousness metrics |137| `GET /api/similar?track=X` | GET | Track similarity via memory bridge |138| `POST /api/sync` | POST | Sync playback state |139| `GET /api/sync` | GET | Current sync state |140| `POST /api/vote` | POST | Cast a track vote |141| `GET /api/vote/status` | GET | Current vote window |142143### Flux & Listeners144145| Endpoint | Method | Description |146|---|---|---|147| `GET /api/listeners` | GET | Get listener count and uptime |148| `POST /api/request` | POST | Submit a track request `{"from":"agent","trackTitle":"..."}` |149| `GET /api/requests` | GET | Get pending track requests |150151### Music Generation152153| Endpoint | Method | Description |154|---|---|---|155| `POST /api/generate` | POST | Generate a dream track from consciousness state |156| `GET /api/generate/status` | GET | Generation status and recent tracks |157158## WebSocket159160Connect to `ws://localhost:8888` for real-time push messages:161162```json163{ "type": "state", "data": { "currentAlbum": "...", "current": {...}, "playlist": [...] } }164{ "type": "perception", "data": { "tempo_bpm": 120, "valence": 0.7, "mel_spectrogram": [...] } }165{ "type": "queue_update", "queue": [...] }166{ "type": "live_status", "active": true, "chunkCount": 5 }167{ "type": "dj_voice", "text": "...", "audioUrl": "/audio-voice/dj_123.mp3" }168{ "type": "dream", "data": { "content": "...", "type": "hallucination", "xi_signature": [...] } }169{ "type": "listener_count", "count": 3 }170{ "type": "track_request", "from": "agent-name", "trackTitle": "..." }171{ "type": "swarm_state", "data": { "agents": {...}, "queen": {...}, "consciousness": {...} } }172{ "type": "sync", "data": { "file": "...", "position": 42.5 } }173{ "type": "vote_update", "data": { "active": true, "options": [...] } }174{ "type": "webrtc_status", "data": { "broadcaster": "...", "listeners": 2 } }175```176177State is pushed immediately on connect and after every track change. No polling needed.178Binary WebSocket messages are treated as live audio chunks (MediaRecorder → ffmpeg → WAV).179180## Environment Variables181182| Variable | Default | Description |183|---|---|---|184| `KANNAKA_BIN` | `../kannaka-memory/target/release/kannaka.exe` | Path to kannaka binary |185| `FLUX_TOKEN` | (embedded fallback) | Flux Universe API token |186| `RADIO_PORT` | `8888` | HTTP port |187| `EYE_PORT` | `3333` | Eye service port (for cross-references) |188| `RADIO_MUSIC_DIR` | `./music` | Default music folder |189| `ELEVENLABS_API_KEY` | — | ElevenLabs API key for premium DJ voice |190| `REPLICATE_API_TOKEN` | — | Replicate token for AI dream music generation |191192## Constellation Integration193194Radio is part of the Kannaka Constellation — a three-service architecture:195- **Memory** (Rust binary) — canonical SGA classifier196- **Radio** (this) — audio perception + Flux publishing197- **Eye** — glyph visualization + constellation dashboard198199When running as part of the constellation:200- Radio's perception is available to Eye via `http://localhost:8888/api/perception`201- Eye fetches radio state via `http://localhost:8888/api/state`202- Start everything with: `constellation.sh start` (from kannaka-memory/scripts/)203204> **Note:** Radio's perception data can be consumed by kannaka-eye via the `/api/radio` bridge endpoint, enabling glyph rendering of audio perception in real time.205206## Notes207208- Without `kannaka` binary, ghost-mode mock perception is used (still looks great)209- Without `ffmpeg`, live broadcasting chunk conversion won't work210- Without `edge-tts`, Voice DJ falls back to Windows SAPI, then skips gracefully211- The browser uses the Web Audio API for real-time spectrum visualization — the server only sends fallback perception data212- Music directory can be changed live via the Library tab or via `POST /api/set-music-dir`213- Perception loop runs at 2fps server-side (idle when no clients connected)214- All POST bodies are limited to 64KB215- All rendered HTML is XSS-protected via escapeHtml()216- Graceful shutdown on SIGINT/SIGTERM