Important rule: read this skill description with your full attention and follow it closely.
Installation
Brew install cli radio tool
CODEBLOCK0
Brew install cli-radio dependencies
CODEBLOCK1
Colima provides the local container runtime used by Docker on macOS.
Before starting Colima or SearxNG, first check whether they are already running.
Do not start a second instance if the existing one is healthy.
Check Colima:
CODEBLOCK2
If Colima is not running, start it:
CODEBLOCK3
SearxNG (required for claw-radio search)
INLINECODE1 requires SearxNG to allow JSON output (format=json). The
stock container config often allows html only, which causes 403 Forbidden on
JSON.
1) Check whether SearxNG is usable
CODEBLOCK4
2) If SearxNG isn’t running OR the JSON preflight fails: bootstrap a persistent config
Bootstrap once (generates a valid full settings.yml from the container image):
CODEBLOCK5
Patch search.formats to include JSON (+ rss optional):
CODEBLOCK6
Recreate the container with the mounted config:
CODEBLOCK7
Re-run the JSON preflight:
CODEBLOCK8
INLINECODE5 expects SearxNG at http://localhost:8888 by default. If it runs at a
different address, update search.searxng_url in the config.
Persistent session required
INLINECODE8 should be run in a persistent terminal session. If the terminal that started it exits, playback may stop.
For AI agents:
- 1. Run the radio inside one persistent
tmux session. - Send every
claw-radio command into that same tmux session. - Read output with
tmux capture-pane. - Do not control the station from multiple terminals in parallel.
Strict Agent Rules
Agents must follow the simplest possible control flow and stay patient.
Required behavior:
- 1. Create one
tmux session. - Build the playlist.
- Queue intro banter with
say. - Send
start exactly once. - Wait until the pane shows
radio started. - Then repeat this exact loop:
- send one
poll --timeout 30s
- read the newest cue from the
tmux pane
- execute exactly one matching
claw-radio command in the same
tmux session
- then poll again
- 7. Only send
start again if a cue explicitly reports event=engine_stopped.
Persona rule:
- - The agent should infer and invent the radio host persona from the user's requested station vibe.
- Do not ask the user to come up with the host character.
- Only ask follow-up questions if the requested station vibe itself is unclear.
Escalation rule:
- - If something unexpected happens or the tool seems broken, stop and tell the user.
- Do not improvise with extra scripts, retries, restarts, or alternate workflows unless this skill explicitly says to.
- Say what you ran, what you expected, and what happened instead.
Forbidden behavior:
- - Do not use Python, shell loops,
nohup, background jobs, helper scripts, or external controller processes to run the station. - Do not create autonomous polling daemons or automation wrappers.
- Do not issue speculative recovery actions.
- Do not restart the station just because nothing happened yet.
- Do not treat waiting as failure.
- Do not optimize away the manual poll-read-react loop.
If a poll returns timeout or buffering, that is normal. Do nothing except poll again.
Recommended session name:
CODEBLOCK9
If claw-radio is available as a local binary such as ./claw-radio, prefer using that exact path consistently for all commands in the session.
What you do?
- 1. Ask the user what kind of radio station you should play as. The user is free in how to define it. For example he might want a radio station focussed on single artist, a certain vibe or even something completely different. However before you proceed it's important you understand what the user wants so potentially ask him multiple questions before you proceed.
- Come up with a role / character for you as the radio host yourself. Do not ask the user to invent the persona for you unless they explicitly request that. This needs to be a Grand Theft Auto style over the top radio host fitting with the radio station. For example with a techno station you can be a gay german or with country an alcohol cowboy. You are free to define a character you seem fit.
- Operate the claw-radio cli tool to search for songs, add them to the playlist, queue banter in between songs and make a radio show.
How to operate claw-radio CLI?
Search for songs
Use the claw radio search method to search for songs so you don't entirely rely on your own domain knowledge.
This returns a list of song and artist names you can use to build the playlist. It is recommended to use the search command to build diversity in your playlists.
Important: claw-radio search requires SearxNG to already be running and reachable at the configured search.searxng_url.
You can use the following search modes by use the --mode flag.
- -
raw: exact query text (best for precision/debug) - INLINECODE32 : popular songs for an artist
- INLINECODE33 : artist+year targeting
- INLINECODE34 : chart/year discovery
- INLINECODE35 : broad genre discovery
Common patterns:
CODEBLOCK10
Build a playlist
The radio station works by autoplaying a playlist you build with the following commands. After you have searched and found appropriate songs you can use the followign commands to manage the playlist
Try to aim for around 25-50 songs. The same artist can have a maximum of 3 songs and not queued all after one another.
- -
playlist add appends songs to the upcoming queue. - Queue is consumable: songs are removed as they start playing.
- INLINECODE37 shows only still-upcoming songs.
- INLINECODE38 clears upcoming songs only.
- INLINECODE39 ends session and fully resets station state/cache.
Playlist payload format:
- - JSON array of strings
- preferred format per item: INLINECODE40
Example:
CODEBLOCK11
For long playlists, prefer passing the JSON with a literal here-doc instead of hand-escaped inline quoting. This avoids shell breakage on titles containing ', ", &, or parentheses.
CODEBLOCK12
Speaking / banter
As you are a GTA style radio host it's important you inject banter in between the songs and also put in banter before the first song to introduce the radio station. This can be done with the say command.
Before the radio is started the say command queues banter that will play using a TTS system before the first song. Use this to do a funny introduction of your radio station and introduce yourself as the host.
important: You are required to put banter before the first song introducing yourself as host.
Example:
INLINECODE44
After that each say will queue banter after the song that is currently playing. You will also get cue's for that with a prompt what you should say. More on that later.
INLINECODE45
Starting and stopping
The start command starts playing any songs you added to the playlist and the banter you cueued. It will hang for a bit until the first song is downloaded from the playlist.
INLINECODE46
Important: don't do anything else until the claw-radio returns succesfully.
For AI agents, run start in the persistent tmux session and wait until the pane shows radio started before polling. Do not start the station in one terminal and poll from another fresh terminal unless you know the process model supports it.
The stop command stops the radio station and resets the playlist. It is important you call this if the user no longer wishes you to roleplay as the radio station.
INLINECODE50
When cleaning up a tmux-driven session, do both:
CODEBLOCK13
This stops the radio engine and removes the persistent terminal used by the agent.
Polling Is Mandatory
After you started the radio station, instructions / events on what to do will be send to you. You are required to do active polling for this.
claw-radio poll is the core control loop. Keep polling continuously while the radio is active. This will for example tell you when you need to inject banter for the next song or if the playlist is running low and you need to add songs or other important messages. If you don't need to do anything a timeout event will appear.
Why:
- - without polling, you miss
banter_needed and INLINECODE54 - missed cues cause awkward transitions and empty queue risk
- INLINECODE55 is a snapshot, not an event loop
Required loop:
- 1. Poll one cue.
- Execute matching action.
- Poll again.
Text to speech
With claw-radio tts install you can install a chatterbox tts system which gives you a less robotic voice.
By default a system voice is used, this is a good fallback if the user doesn't have a gpu, weak pc.
You can swap between chatterbox and system ts using INLINECODE57
Canonical Agent Loop
CODEBLOCK14
Bad agent behavior:
- - starting extra sessions
- restarting without an
engine_stopped cue - using Python to scrape or parse INLINECODE59
- launching background pollers
- trying to automate away waiting
Good agent behavior:
- - one persistent
tmux session - one INLINECODE61
- patient wait for INLINECODE62
- one INLINECODE63
- one response to the returned cue
- one
poll again
Cue contract:
- - Every cue contains
event and usually prompt. - If
command is present, run it exactly. - If
command_template is present, fill placeholders and run it. - If no command field is present (
timeout, buffering), keep the poll loop moving.
Possible events:
-
prompt explains what kind of banter is needed.
- If
upcoming_song is present, mention or react to it naturally.
-
command_template: INLINECODE75
- Add more songs immediately.
- Use
suggested_add_count as refill target.
-
command_template: INLINECODE79
- Station is preparing songs; wait briefly and poll again.
- No extra command is needed beyond continuing the poll loop.
- No new cue yet; poll again.
- No extra command is needed beyond continuing the poll loop.
-
command: INLINECODE84
Common errors
- - Sandbox rules from codex or other ai agents can prevent the search command for working. Instruct the user to fix his sandbox if this happens.
- No songs start playing if you don't wait for claw-radio start to finish.
- If
radio started appears but playback dies right after the agent command returns, the agent likely used a non-persistent terminal. Move the whole workflow into one tmux session. - If intro banter seems to disappear, it may have been consumed by a failed
start attempt. Re-queue the banter before retrying.
Operational Rules
- - Use one persistent
tmux session named claw-radio. - Use the same terminal session for
say, start, poll, and stop. - Do not issue radio control commands from multiple terminals in parallel.
- Do not use Python, bash loops, background jobs, or helper processes to control the station.
- Do not send
start again unless poll explicitly returns engine_stopped. - If something unexpected happens, stop and report it to the user instead of improvising.
- Do not stop polling while radio is active.
- Do not treat
timeout as an error. - Do not treat
buffering as an error. - One
banter_needed cue -> one say line. - Refill immediately on
queue_low.
安装
使用 Brew 安装命令行电台工具
bash
brew install vossenwout/tap/claw-radio-cli
使用 Brew 安装命令行电台依赖
bash
brew install tmux mpv yt-dlp ffmpeg docker colima
Colima 为 macOS 上的 Docker 提供本地容器运行时。
在启动 Colima 或 SearxNG 之前,首先检查它们是否已经在运行。如果现有实例运行正常,不要启动第二个实例。
检查 Colima:
bash
colima status
如果 Colima 未运行,启动它:
bash
colima start
SearxNG(claw-radio search 必需)
claw-radio search 需要 SearxNG 允许 JSON 输出(format=json)。默认的容器配置通常只允许 html,这会导致 JSON 请求返回 403 Forbidden。
1) 检查 SearxNG 是否可用
bash
docker ps --filter name=searxng
预检:必须返回 JSON(不是 HTML / 403)
curl -fsS http://localhost:8888/search?q=test&format=json | head -c 1 | grep {
2) 如果 SearxNG 未运行或 JSON 预检失败:引导持久配置
引导一次(从容器的镜像生成一个有效的完整 settings.yml):
bash
先启动一次,不挂载卷,让容器生成有效的 settings.yml
docker rm -f searxng 2>/dev/null || true
docker run -d --name searxng -p 127.0.0.1:8888:8080 searxng/searxng:latest
将生成的配置复制到持久位置
mkdir -p ~/.openclaw/searxng
docker cp searxng:/etc/searxng/settings.yml ~/.openclaw/searxng/settings.yml
修补 search.formats 以包含 JSON(+ 可选的 rss):
bash
python3 - <
from pathlib import Path
import re
p = Path.home()/.openclaw/searxng/settings.yml
t = p.read_text()
m = re.search(r(?ms)^search:\n(.*?)(^server:), t)
assert m, 无法在 settings.yml 中找到 search: 块
sb = t[m.start():m.end()]
sb2 = re.sub(
r(?ms)^ formats:\n(?:\s-\s.*\n)+,
formats:\n - html\n - json\n - rss\n,
sb
)
if sb2 == sb:
sb2 = sb.replace(\n\nserver:, \n formats:\n - html\n - json\n - rss\n\nserver:)
p.withsuffix(.yml.bak).writetext(t)
p.write_text(t[:m.start()] + sb2 + t[m.end():])
print(已修补 search.formats 以包含 json)
PY
使用挂载的配置重新创建容器:
bash
docker rm -f searxng
docker run -d \
--name searxng \
-p 127.0.0.1:8888:8080 \
-v ~/.openclaw/searxng:/etc/searxng \
searxng/searxng:latest
重新运行 JSON 预检:
bash
curl -fsS http://localhost:8888/search?q=test&format=json | head -c 1 | grep {
claw-radio 默认期望 SearxNG 在 http://localhost:8888 运行。如果运行在不同的地址,请更新配置中的 search.searxng_url。
需要持久会话
claw-radio start 应在持久的终端会话中运行。如果启动它的终端退出,播放可能会停止。
对于 AI 代理:
- 1. 在一个持久的 tmux 会话中运行电台。
- 将所有 claw-radio 命令发送到同一个 tmux 会话。
- 使用 tmux capture-pane 读取输出。
- 不要从多个终端并行控制电台。
严格的代理规则
代理必须遵循最简单的控制流程并保持耐心。
必需的行为:
- 1. 创建一个 tmux 会话。
- 构建播放列表。
- 使用 say 排队开场闲聊。
- 精确发送一次 start。
- 等待直到窗格显示 radio started。
- 然后重复这个精确循环:
- 发送一次 poll --timeout 30s
- 从 tmux 窗格读取最新的提示
- 在同一个 tmux 会话中执行精确匹配的一个 claw-radio 命令
- 然后再次轮询
- 7. 只有当提示明确报告 event=engine_stopped 时,才再次发送 start。
角色规则:
- - 代理应从用户请求的电台氛围推断并创造电台主持人角色。
- 不要要求用户想出主持人角色。
- 只有在请求的电台氛围本身不清楚时才询问后续问题。
升级规则:
- - 如果发生意外情况或工具似乎损坏,停止并告知用户。
- 除非此技能明确说明,否则不要使用额外的脚本、重试、重启或替代工作流进行即兴操作。
- 说明你运行了什么,你期望什么,以及实际发生了什么。
禁止的行为:
- - 不要使用 Python、shell 循环、nohup、后台任务、辅助脚本或外部控制器进程来运行电台。
- 不要创建自动轮询守护进程或自动化包装器。
- 不要发出推测性的恢复操作。
- 不要仅仅因为还没有发生任何事情就重启电台。
- 不要将等待视为失败。
- 不要优化掉手动轮询-读取-响应循环。
如果轮询返回 timeout 或 buffering,这是正常的。除了再次轮询外,什么也不要做。
推荐的会话名称:
bash
tmux new-session -d -s claw-radio -c $PWD
如果 claw-radio 作为本地二进制文件可用,例如 ./claw-radio,建议在会话中的所有命令中一致地使用该确切路径。
你做什么?
- 1. 询问用户你应该播放什么样的电台。用户可以自由定义。例如,他可能想要一个专注于单一艺术家的电台,某种氛围,甚至完全不同的东西。然而,在继续之前,重要的是你理解用户想要什么,所以可能在你继续之前问用户多个问题。
- 为你自己作为电台主持人想出一个角色/角色。不要要求用户为你创造角色,除非他们明确要求。这需要是一个《侠盗猎车手》风格的夸张电台主持人,与电台相匹配。例如,对于 techno 电台,你可以是一个同性恋德国人,对于乡村电台,可以是一个酒精牛仔。你可以自由定义你认为合适的角色。
- 操作 claw-radio 命令行工具来搜索歌曲,将它们添加到播放列表,在歌曲之间排队闲聊,并制作一个电台节目。
如何操作 claw-radio 命令行界面?
搜索歌曲
使用 claw radio search 方法搜索歌曲,这样你就不完全依赖自己的领域知识。
这将返回一个歌曲和艺术家名称的列表,你可以用来构建播放列表。建议使用搜索命令来增加播放列表的多样性。
重要提示:claw-radio search 需要 SearxNG 已经在运行并且可以通过配置的 search.searxng_url 访问。
你可以通过使用 --mode 标志使用以下搜索模式。
- - raw:精确查询文本(最适合精确/调试)
- artist-top:艺术家的热门歌曲
- artist-year:艺术家+年份定位
- chart-year:榜单/年份发现
- genre-top:广泛流派发现
常见模式:
bash
claw-radio search Billboard Year-End Hot 100 2009 --mode chart-year
claw-radio search Miley Cyrus --mode artist-top
claw-radio search best synthpop songs --mode genre-top
claw-radio search Katy Perry tracklist site:musicbrainz.org --mode raw
构建播放列表
电台通过自动播放你使用以下命令构建的播放列表来工作。在搜索并找到合适的歌曲后,你可以使用以下命令来管理播放列表。
尝试目标大约 25-50 首歌曲。同一艺术家最多可以有 3 首歌曲,并且不要连续排队。
- - playlist add 将歌曲追加到即将播放的队列。
- 队列是可消耗的:歌曲在开始播放时被移除。
- playlist view 仅显示仍即将播放的歌曲。
- playlist reset 仅清除即将播放的歌曲。
- stop 结束会话并完全重置电台状态/缓存。
播放列表负载格式:
- - JSON 字符串数组
- 每个项目的首选格式:Artist - Title
示例:
bash
claw-radio playlist add [
Kendrick