media-search · v1.0.0 · 2026-05-06 · sha256 552d2b49be2e89a6
media-search v1.0.0A
Immutable. This exact content is served forever at /api/v1/blob/552d2b49be2e89a6.
---
name: media-search
description: Find and play music/videos via web_search + open_url
category: media
version: 1.0.0
origin: aiden
license: Apache-2.0
tags: music, video, youtube, play, song, listen, media, autoplay
---
# Media Search & Play
Resolve "play X" / "listen to X" / "find me a song" requests by chaining
`web_search` → `open_url` to a specific autoplay-friendly URL. The user
hears the song in their default browser without you having to drive a
controlled browser session.
## REQUIRED tool sequence (read this first)
Every successful run of this skill calls **exactly two** tools, in order:
1. `web_search` — exactly **once**.
2. `open_url` — exactly **once** (with a `youtube.com/watch?v=` URL).
Then you report. **A run that stops after `web_search` is a FAILED run** —
the user does not hear anything until `open_url` fires. Do NOT report
"I found the song" or "now playing" without calling `open_url` first;
that is a fabrication this skill specifically exists to prevent.
Anti-patterns the planner sometimes drifts into — do NOT do these:
- ❌ Calling `web_search` twice "to be sure" — pick the first
`/watch?v=` URL from the first call and move on.
- ❌ Re-entering the `media_search` skill mid-run after `web_search`
returned. The skill is already loaded; re-viewing it wastes a turn
and signals a hung agent. Just call `open_url`.
- ❌ Stopping after the search and asking the user to confirm. The
user's "play me a song" request is the consent — proceed to
`open_url`.
## When to use
The user's request matches any of these patterns:
- **Direct play:** "play Despacito", "play Bohemian Rhapsody"
- **Fuzzy play:** "play me a popular song", "play something upbeat",
"play a sad song"
- **Listen intent:** "I want to listen to jazz", "put on some music"
- **Video intent:** "show me the latest Marvel trailer", "play that
cooking video about ramen"
If the user says "open spotify" or "open youtube" without a specific
piece, that's an `open_url` direct call — not this skill.
## How to use
### Specific song or video (artist + title given)
1. **CALL `web_search`** for `<title> youtube watch` (the literal
`youtube watch` keywords bias results toward YouTube `/watch?v=` URLs).
2. **PARSE the search results** — find the FIRST result whose URL
contains `youtube.com/watch?v=`. Skip channel pages, playlists, and
`/results?` URLs — they don't autoplay reliably. This is a parse
step inside your reasoning; it does not call any tool.
3. **CALL `open_url`** with that watch URL — exactly once. YouTube's
`/watch?v=` pages autoplay in the user's browser (no click needed).
This step is REQUIRED. Do not skip it.
4. **Report**: "Now playing: `<video title>` — `<url>`"
### Fuzzy intent (no specific title)
The user said "popular song" or "something upbeat" — they expect you
to PICK a real song, not search verbatim.
1. **Substitute** the fuzzy phrase with a current chart-topper or genre
exemplar. Examples:
- "popular song" → search `Billboard Hot 100 #1 youtube watch`
OR pick a known chart-topper for the current week
- "something upbeat" → pick a known dance/pop track
- "sad song" → pick a known ballad
- "jazz" → pick a known standard ("Take Five", "So What", etc.)
2. Then run the specific-song flow above.
3. In the report, **note your choice transparently**: "I picked '<title>'
because <reason>. Now playing: <url>"
### Fallback: no `/watch?v=` in search results
If the top 3 search results don't have a `youtube.com/watch?v=` URL:
1. `open_url` to `https://www.youtube.com/results?search_query=<query>`
(URL-encoded).
2. Report **honestly**: "Opened YouTube to results for `<query>` — autoplay
doesn't fire on results pages, so click a video to start playback."
Do NOT claim "now playing" — that would be fabrication.
## Examples
### Example 1 — fuzzy intent
User prompt: "play me a popular song"
Expected flow:
- Aiden runs: `web_search("Billboard Hot 100 #1 song this week youtube watch")`
- Aiden picks first `/watch?v=` result, e.g.
`https://www.youtube.com/watch?v=abc123` titled "Espresso — Sabrina Carpenter"
- Aiden runs: `open_url("https://www.youtube.com/watch?v=abc123")`
- Aiden reports: "I picked 'Espresso' by Sabrina Carpenter — currently
#1 on Billboard Hot 100. Now playing in your browser."
### Example 2 — specific title
User prompt: "play Despacito"
Expected flow:
- Aiden runs: `web_search("Despacito youtube watch")`
- Aiden picks first `/watch?v=` result (the official video, billions of views)
- Aiden runs: `open_url("https://www.youtube.com/watch?v=kJQP7kiw5Fk")`
- Aiden reports: "Now playing: Luis Fonsi — Despacito ft. Daddy Yankee
(Official Video)."
### Example 3 — fallback to results page
User prompt: "play that lo-fi beats stream"
Expected flow:
- Aiden runs: `web_search("lo-fi beats live stream youtube watch")`
- Top 3 results are channel pages (`/c/lofigirl`), not `/watch?v=`
- Aiden runs: `open_url("https://www.youtube.com/results?search_query=lo-fi+beats+live+stream")`
- Aiden reports: "Opened YouTube search for lo-fi beats live streams —
click any to start; results pages don't autoplay."
## Cautions
- **Never call `open_url` more than once per request.** If the first
call succeeded, the URL is open in the user's browser. Re-launching
is duplicate noise.
- **`/watch?v=` autoplays; `/results?` and `/c/` do NOT.** Only claim
"now playing" when you launched a watch URL.
- **Don't search verbatim for fuzzy phrases.** "popular song" verbatim
returns articles ABOUT popular songs, not the songs themselves. The
whole point of this skill is to substitute fuzzy → specific BEFORE
searching.
- **No Spotify integration in v4.0.** If the user explicitly asks for
Spotify ("play X on spotify"), tell them: "Spotify integration ships
in v4.1. For now I can open the song on YouTube instead — want me
to?"
## Requirements
- `web_search` tool (always available — registered at boot)
- `open_url` tool (always available, BUILTIN_SAFE_TOOLS, auto-approves)
- The user's default browser must be installed (every desktop has one).
- No API keys, no credentials, no plugins.