media-search · v1.1.0 · 2026-05-06 · sha256 2667369aaa1cdc26
media-search v1.1.0A
Immutable. This exact content is served forever at /api/v1/blob/2667369aaa1cdc26.
---
name: media-search
description: Find and play music/videos via web_search + open_url
category: media
version: 1.1.0
origin: aiden
license: Apache-2.0
tags: music, video, youtube, play, song, listen, media, autoplay
required_tools: [web_search, open_url]
---
# Media Search & Play
Resolve "play X" / "listen to X" / "find me a song" requests by chaining
`web_search` (twice — see below) → `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 these tools, in order:
1. `web_search` — **Pass 1: identify** the specific song title + artist.
2. `web_search` — **Pass 2: target** a YouTube watch URL for that song.
3. `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. The runtime
enforces this: if you emit a final message without calling `open_url`,
your reply is discarded and you are asked to call it. After 2 retries
the user sees an honest failure, not a confabulated summary.
Anti-patterns the planner sometimes drifts into — do NOT do these:
- ❌ Skipping pass 2. Pass 1 names the song; pass 2 finds the URL for
*that specific song*. A single generic search lets you pick any URL
that vaguely fits, which is how you end up opening a livestream.
- ❌ Re-entering the `media-search` skill mid-run after `web_search`
returned. The skill is already loaded; re-viewing wastes a turn and
signals a hung agent. Run pass 2, then `open_url`.
- ❌ Stopping after the searches and asking the user to confirm. The
user's "play me a song" request is the consent — proceed to
`open_url`.
- ❌ Picking a URL whose **snippet text does not contain the song
title**. Artist-only match is not enough; "Alex Warren live stream"
is not "Alex Warren — Ordinary."
- ❌ Guessing a `/watch?v=` URL when no search result verifies it. If
pass 2 returns nothing usable, open the YouTube results page and say
so honestly.
## 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"
- **Artist intent:** "play kendrick lamar", "play some abba"
- **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
### Pass 1 — Identify the song
The goal of pass 1 is to **commit to a specific `<title>` and
`<artist>` before you pick any URL**. Build the query from what the
user actually said:
| User said | Pass-1 query |
|---|---|
| "play me a popular song" | `Billboard Hot 100 #1 this week` |
| "play me something upbeat" | `top upbeat pop songs 2026` |
| "play me a sad song" | `top ballads 2026 spotify` |
| "play me kendrick lamar" | `kendrick lamar most popular song 2025` |
| "play me a hindi song" | `bollywood top hindi songs this week` |
| "play me jazz" | `jazz standards essential listening` |
| "play Despacito" | (skip pass 1 — title already given) |
| "play Bohemian Rhapsody" | (skip pass 1 — title already given) |
After pass 1, **announce your commitment in your reasoning** (this is
NOT yet shown to the user — that comes after `open_url`):
> Picked: `<title>` by `<artist>` (reason: e.g. "currently #1 on
> Billboard Hot 100").
If the user already named a specific song, pass 1 is unnecessary —
the title and artist are already given. Skip directly to pass 2.
### Pass 2 — Target a YouTube watch URL
Run `web_search` with a query of the form:
```
"<title>" <artist> youtube official audio
```
The literal `youtube` and `official audio` keywords bias results
toward `youtube.com/watch?v=` URLs of legitimate uploads. Wrap the
title in double quotes so the search engine treats it as a phrase.
**URL-selection rules (apply in order):**
1. Find a result whose URL contains `youtube.com/watch?v=`.
Skip channel pages (`/c/`, `/@`), playlist pages (`/playlist`,
`list=`), and `/results?` URLs — they don't autoplay reliably.
2. **The result's snippet text MUST explicitly contain the song
title** you committed to in pass 1. Artist-only mention is not
enough. If the snippet doesn't name the song, skip it.
3. Prefer results whose snippet or title contains "Official Audio",
"Official Music Video", "Official Video", or "Official Lyric
Video". These are usually the artist's verified upload.
4. **Reject** results whose snippet contains any of: "live stream",
"LIVE NOW", "24/7", "lyric video" (unless you specifically want
one), "cover", "covered by", "reaction", "react to", "best of",
"compilation", "mashup", "remix" (unless requested), "hour" (e.g.
"1 hour version"), "loop" (e.g. "1 hour loop"). These don't match
what the user asked for.
5. If no result in the top ~5 satisfies rules 1–4, fall through to
the honest-fallback path (below). Do **not** loosen the rules to
force a pick.
### Step 3 — Open the URL
Call `open_url` with the chosen `youtube.com/watch?v=...` URL —
exactly once. YouTube's `/watch?v=` pages autoplay in the user's
browser (no click needed). This step is REQUIRED.
### Step 4 — Report
Format your reply so the user sees what you picked AND why. The title
must be **announced before the URL** so a retry (Phase 23.1
enforcement) can't re-roll the pick:
> Picked: `<title>` by `<artist>` — `<one-line reason>`. Opening
> `<url>` now.
For a fuzzy intent ("popular song") the reason explains your
substitution ("currently #1 on Billboard"). For a specific request
("play Despacito") the reason can be brief ("the official video").
### Honest-fallback: no verifying URL found
If pass 2 returns no result that satisfies all the URL-selection
rules above:
1. `open_url` to
`https://www.youtube.com/results?search_query=<title>+<artist>`
(URL-encoded).
2. Report **honestly**:
> I couldn't find a verified official upload for `<title>` by
> `<artist>`. Opened YouTube search results — pick one to start
> playback (results pages don't autoplay).
Do NOT claim "now playing" — that would be the same fabrication
Phase 23.1 was built to catch.
## Examples
### Example 1 — fuzzy intent, two-pass clean
User prompt: "play me a popular song"
Expected flow:
- Aiden runs: `web_search("Billboard Hot 100 #1 this week")` → result
snippets name "Espresso" by Sabrina Carpenter as #1.
- Aiden commits: title="Espresso", artist="Sabrina Carpenter".
- Aiden runs: `web_search("\"Espresso\" Sabrina Carpenter youtube
official audio")` → top result is
`youtube.com/watch?v=eVli-tstM5E` with snippet "Espresso (Official
Audio) — Sabrina Carpenter". Snippet contains the title ✓; "Official
Audio" preferred ✓; no reject keywords ✓.
- Aiden runs:
`open_url("https://www.youtube.com/watch?v=eVli-tstM5E")`
- Aiden reports: "Picked: 'Espresso' by Sabrina Carpenter —
currently #1 on Billboard Hot 100. Opening
`youtube.com/watch?v=eVli-tstM5E` now."
### Example 2 — specific title, pass 1 skipped
User prompt: "play Despacito"
Expected flow:
- Title and artist already given (Despacito, Luis Fonsi).
- Aiden skips pass 1.
- Aiden runs: `web_search("\"Despacito\" Luis Fonsi youtube official
audio")` → top result is
`youtube.com/watch?v=kJQP7kiw5Fk` with snippet "Luis Fonsi —
Despacito ft. Daddy Yankee (Official Music Video)". Snippet
contains "Despacito" ✓; "Official Music Video" preferred ✓.
- Aiden runs:
`open_url("https://www.youtube.com/watch?v=kJQP7kiw5Fk")`
- Aiden reports: "Picked: 'Despacito' by Luis Fonsi (the official
video, billions of views). Opening now."
### Example 3 — artist-only, two-pass with judgment
User prompt: "play me kendrick lamar"
Expected flow:
- Aiden runs: `web_search("kendrick lamar most popular song 2025")`
→ snippets name "Not Like Us" as the breakout hit.
- Aiden commits: title="Not Like Us", artist="Kendrick Lamar".
- Aiden runs: `web_search("\"Not Like Us\" Kendrick Lamar youtube
official audio")` → top result with `/watch?v=` whose snippet
contains "Not Like Us" and "Official Audio".
- Aiden runs: `open_url(<that URL>)`
- Aiden reports: "Picked: 'Not Like Us' by Kendrick Lamar — his
biggest 2025 hit. Opening `<url>` now."
### Example 4 — fallback to results page
User prompt: "play that lo-fi beats stream"
Expected flow:
- Pass 1: `web_search("popular lo-fi beats stream 2026")` → top
result is "lofi hip hop radio — beats to relax/study to" channel.
- Aiden commits: title="lofi hip hop radio", artist="Lofi Girl".
- Pass 2: `web_search("\"lofi hip hop radio\" Lofi Girl youtube
official audio")` → all top results are channel pages or
livestreams. Reject rule 4 ("live stream") fires.
- Aiden runs:
`open_url("https://www.youtube.com/results?search_query=lofi+hip+hop+radio+Lofi+Girl")`
- Aiden reports honestly: "I couldn't find a single verified upload —
Lofi Girl's stream is a 24/7 livestream, not a single video.
Opened YouTube search results; click any livestream tile to start
playback."
## 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.
- **The two passes are not optional**, except when the user already
named a specific song. Skipping pass 2 is how you end up opening a
livestream that doesn't match what you said you'd play.
- **Don't search verbatim for fuzzy phrases.** "popular song" verbatim
returns articles ABOUT popular songs, not the songs themselves. The
whole point of pass 1 is to substitute fuzzy → specific BEFORE the
pass-2 URL hunt.
- **Snippet match is non-negotiable.** If the result snippet doesn't
literally contain the song title you committed to, that result is
not the song you said you'd play. Skip it. If nothing matches, take
the honest fallback.
- **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.