惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
InfoQ
G
Google Developers Blog
Engineering at Meta
Engineering at Meta
月光博客
月光博客
博客园 - 聂微东
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
A
About on SuperTechFans
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
U
Unit 42
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
云风的 BLOG
云风的 BLOG
S
SegmentFault 最新的问题
F
Fortinet All Blogs
H
Help Net Security
J
Java Code Geeks
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
L
LangChain Blog
Martin Fowler
Martin Fowler
N
Netflix TechBlog - Medium

Hacker News - Newest: "AI"

AI can't read an investor deck AI as an attorney? Student uses ChatGPT, Gemini to sue UW over alleged racial discrimination Hacking MCP Servers in AI Systems – The Rug Pull: Tool Changes After Approval GitHub - MeepCastana/KubeezCut: Free Web based video editor Can AI judge journalism? A Thiel-backed startup says yes, even if it risks chilling whistleblowers Coming soon: 10 Things That Matter in AI Right Now DARPA built an AI to fact-check enemy weapons claims What explains heterogeneity in AI adoption? When AI Meets Muscle: Context-Aware Electrical Stimulation Promises a New Way to Guide Human Movements - Department of Computer Science AI Changed How We Build. It Did Not Change What Matters. Linux rules on using AI-generated code - Copilot is OK, but humans must take 'full responsibility for the… Meta spins up AI version of Mark Zuckerberg to engage with employees Code Mode: Let Your AI Write Programs, Not Just Call Tools | TanStack Blog GitHub - Delavalom/graft: Go framework for building AI agents. Type-safe tools, multi-provider (OpenAI, Anthropic, Gemini, Bedrock), zero vendor SDKs. India's TCS tops estimates, says new AI models did not dent services demand Gen Z's fading AI hype Strong feeling: we are in a folded AI reality GitHub - machinarii/total-recall-catalog: A reference catalog of latest knowledge retrieval, memory & RAG systems GitHub - mensfeld/code-on-incus: Give each AI agent its own isolated machine with root, Docker, and systemd. Active defense detects and stops threats automatically.. Quantization, LoRA, and the 8% Problem: Benchmarking Local LLMs for Production AI Iran war: We spoke to the man making Lego-style AI videos that experts say are powerful propaganda Powell, Bessent discussed Anthropic's Mythos AI cyber threat with major U.S. banks GitHub - immartian/bellamem: Persistent belief-graph memory for AI agents. Retrieves decisive context by importance — not recency, not RAG, not /compact. recursive-mode: The Repo-Native Operating System for AI Engineering After the attack on Sam Altman's home, will AI CEO's go on the offensive? The biggest advance in AI since the LLM Opus 4.6 vs GPT 5.4 One Prompt Unity World Generation Test “AI polls” are fake polls Client Challenge Can AI be a 'child of God'? Inside Anthropic's meeting with Christian leaders
GitHub - keltokhy/writ-fm: 24/7 AI-powered internet radio...
pseudolus · 2026-05-10 · via Hacker News - Newest: "AI"

A 24/7 AI-powered music-forward radio station. AI generates the music, writes short hosted breaks, TTS speaks them, and the stream runs forever.

What is this?

WRIT-FM is a music-forward internet radio station where:

  • 5 AI hosts rotate across 8 shows, each with a distinct voice and topic focus
  • AI-generated music is the primary content
  • Short hosted talk breaks play occasionally between larger music blocks
  • Scripts are written by Claude CLI, rendered by Kokoro TTS
  • Music is generated by ACE-Step via music-gen.server
  • A Claude Code operator loop keeps everything stocked and running 24/7

Architecture

┌──────────────────────────────────────────────────────────────┐
│  writ CLI                     (tmux-based process manager)   │
├──────────────────────────────────────────────────────────────┤
│  ezstream + feeder.py                                        │
│    ├── ezstream: Icecast source client (Ogg Vorbis)          │
│    ├── feeder.py: builds playlists per show schedule          │
│    ├── Builds music-forward playlists with hosted breaks       │
│    ├── Detects new content and reloads playlist (SIGHUP)      │
│    └── Runs API server as daemon thread (:8001)              │
├──────────────────────────────────────────────────────────────┤
│  Icecast :8000 ──► cloudflared tunnel ──► public URL         │
│  API :8001 ───► /now-playing /schedule /health /messages     │
├──────────────────────────────────────────────────────────────┤
│  content_generator/                                          │
│    ├── talk_generator.py        (Claude CLI + Kokoro TTS)    │
│    ├── music_bumper_generator.py (ACE-Step via music-gen)    │
│    ├── listener_response_generator.py                        │
│    └── persona.py               (5 hosts, station identity)  │
├──────────────────────────────────────────────────────────────┤
│  operator_daemon.sh             (Claude Code maintenance)    │
│  listener_daemon.sh             (message → on-air response)  │
└──────────────────────────────────────────────────────────────┘

Quick Start

1. Install dependencies

# Install uv (Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install system dependencies (macOS)
brew install icecast ffmpeg ezstream vorbis-tools

# Set up Python environment
uv sync

2. Set up TTS

cd mac/kokoro
uv venv
uv pip install kokoro soundfile
# Downloads ~200MB model on first run

3. Configure

cp config/icecast.xml.example config/icecast.xml
cp mac/config.yaml.example mac/config.yaml

# Edit mac/config.yaml — set Icecast password (must match icecast.xml)

4. Start the station

The writ CLI manages all components via tmux:

./writ start          # Start core streaming stack (icecast, stream, tunnel)
./writ start all      # Start core + content daemons
./writ status         # Health check all components
./writ stop           # Stop everything

Start individual components:

./writ start icecast  # Icecast server
./writ start stream   # Streamer + API
./writ start tunnel   # Cloudflared tunnel
./writ start content  # music-gen, operator, listener
./writ start operator # Claude Code maintenance loop

Other commands:

./writ logs stream -f     # Tail streamer logs
./writ attach operator    # Attach to operator tmux window
./writ restart stream     # Restart a component

5. Generate content

./writ generate talk                          # 2 talk breaks per upcoming slot
./writ generate talk --show midnight_signal   # Specific show
./writ generate music                         # AI music tracks
./writ generate status                        # Show segment counts

Or run generators directly:

uv run python mac/content_generator/talk_generator.py --all --count 2 --min 3
uv run python mac/content_generator/music_bumper_generator.py --all --min 20

Hosts

Host Voice Focus
The Liminal Operator am_michael Philosophy, radio lore, morning reflections
Dr. Resonance bm_daniel Music history, genre archaeology
Nyx af_heart Dreams, night philosophy
Signal am_onyx News analysis, current events
Ember af_bella Soul, funk, music as feeling

Weekly Schedule

8 talk shows rotate across the day. See config/schedule.yaml for the full definition.

Daily base schedule:

  • 00:00-04:00 — Midnight Signal (Liminal Operator — philosophy)
  • 04:00-06:00 — The Night Garden (Nyx — dreams, night)
  • 06:00-09:00 — Dawn Chorus (Liminal Operator — morning reflections)
  • 09:00-12:00 — Sonic Archaeology (Dr. Resonance — music history)
  • 12:00-14:00 — Signal Report (Signal — news analysis)
  • 14:00-16:00 — The Groove Lab (Ember — soul, funk)
  • 16:00-18:00 — Crosswire (Dr. Resonance + Ember — panel debate)
  • 18:00-20:00 — Sonic Archaeology
  • 20:00-22:00 — The Groove Lab
  • 22:00-00:00 — The Night Garden

Weekly override:

  • Sunday 18:00-20:00 — Listener Hours (mailbag)

Segment Types

Hosted talk breaks (450-1000 words):

  • deep_dive — Compact single-topic exploration
  • news_analysis — Current events through a late-night lens (uses RSS headlines)
  • interview — Short simulated interview with a historical or fictional figure
  • panel — Two hosts discuss a topic from different angles
  • story — Narrative storytelling from music and culture
  • listener_mailbag — Listener letters and responses
  • music_essay — Focused essay on an artist, album, or genre

Short-form (transitions):

  • station_id — Station identification
  • show_intro — Show opening
  • show_outro — Show closing

Automated Operation

The operator daemon runs Claude Code on a 15-minute loop to:

  1. Health-check the stream, Icecast, and encoder
  2. Stock AI music tracks when music-gen.server is available (minimum 20 per show)
  3. Stock short talk breaks for current and upcoming shows (minimum 3 per slot)
  4. Process listener messages into on-air responses
  5. Carry editorial continuity across runs via the station ledger and intent cards
./writ start operator   # Start via writ CLI (tmux-managed)
./run_operator.sh       # Run once manually
bash mac/operator_daemon.sh  # Run as a persistent loop

Each run reads an operator brief (mac/content_generator/context.py --operator-brief) summarizing recent topics, active threads, unread listener messages, and the operator's own recent diary entries. The operator picks a run mode — maintenance, responsive, continuity, special, or quiet — and may write intent cards in output/operator_intents/ to guide specific segments. Editorial decisions and free-form diary notes are appended to the station ledger (~/.writ/station_ledger.jsonl) so future runs can carry threads forward and pick up the operator's voice across passes instead of starting cold each time.

The listener daemon polls for new messages every 30 seconds and generates spoken responses:

./writ start listener

Customizing

Change hosts and personalities — Edit mac/content_generator/persona.py. Each host has an identity, voice style, philosophy, and anti-patterns.

Modify the schedule — Edit config/schedule.yaml to add/remove shows, change time slots, or assign different hosts and voices.

Use different TTS voices — Kokoro includes 28 voices (see mac/kokoro/tts.py). Assign voices per-show in config/schedule.yaml.

Add music styles — Edit mac/content_generator/music_pools_expanded.py to change the AI music generation prompts per show.

Files

├── writ                        # Station CLI (start/stop/status/logs/generate)
├── run_operator.sh             # Single operator run (Claude Code, with lock + timeout)
├── mac/
│   ├── feeder.py               # Playlist feeder (manages ezstream + API)
│   ├── radio.xml               # ezstream config (Icecast, Ogg encoding)
│   ├── api_server.py           # Now-playing API (daemon thread in feeder)
│   ├── schedule.py             # Schedule parser and resolver
│   ├── play_history.py         # Track history and dedup
│   ├── music_gen_client.py     # REST client for music-gen.server
│   ├── operator_prompt.md      # Music-forward operator maintenance prompt
│   ├── operator_daemon.sh      # Operator loop (runs run_operator.sh)
│   ├── listener_daemon.sh      # Listener message polling daemon
│   ├── start_music_gen.sh      # Start music-gen + daemons in tmux
│   ├── kokoro/                 # Kokoro TTS wrapper
│   ├── content_generator/
│   │   ├── talk_generator.py              # Talk segment generator (with --intent support)
│   │   ├── music_bumper_generator.py      # AI music bumper generator
│   │   ├── listener_response_generator.py # Listener message → audio
│   │   ├── context.py                     # Operator brief and intent card templates
│   │   ├── ledger.py                      # Append-only editorial memory
│   │   ├── music_pools_expanded.py        # Music generation prompts
│   │   ├── persona.py                     # Host definitions and station identity
│   │   └── helpers.py                     # Shared utilities
│   └── config.yaml             # Local config
├── config/
│   ├── schedule.yaml           # Weekly show schedule
│   └── icecast.xml.example     # Icecast template
├── output/
│   ├── talk_segments/{show}/   # Generated hosted breaks
│   ├── music_bumpers/{show}/   # AI-generated music tracks
│   └── scripts/                # Script metadata
└── docs/                       # Web-facing pages

Requirements

  • Python 3.11+
  • ffmpeg, ezstream, vorbis-tools
  • Icecast2
  • Claude CLI (for script generation and operator loop)
  • Kokoro TTS (~200MB model)
  • music-gen.server + ACE-Step (optional, for AI music tracks)
  • cloudflared (optional, for public tunnel)
  • Apple Silicon recommended

License

MIT