## browseAndPlay Tool Spec

Plays a YouTube video on the shared screen so it appears on the Go-Live
broadcast. Used when the user asks the assistant to play / watch a song, music
video, or clip.

### Behaviour

- Public schema is a required `query` string (what to play) plus an optional
  `index` integer (1-based position in the search results, counted from the top
  of the list). `index` defaults to `1` (first result), so existing callers and
  "play X" requests are unchanged; "play the 3rd video" / "play the second one"
  map to `index=3` / `index=2`.
- **Mode-gated**: only acts when `STREAM_BROWSER` is true (`cfg.stream_browser`).
  In voice-only mode (false) there is no screen to show, so it returns a short
  message and does nothing.
- Drives the on-screen Chrome by subprocessing the Node CDP helper
  `bot/scripts/stream-test/browse-search.mjs <query> youtube <index>`, which
  searches YouTube and plays the chosen result on display `:1`. The broadcast
  captures that display, so the playback is what viewers see.
  - The helper clicks the `index`-th `a#video-title` in the results list. The
    index is clamped to the number of results actually returned, so asking for a
    position beyond the list plays the last available result rather than failing.
- Returns `success` with the played video's title (and the resolved `index`), or
  a failure message if the helper/Chrome is unavailable. It does NOT make an LLM
  call.

### Principles

- The Node layer owns Chrome/CDP; the Python tool only shells out to it, so the
  brain stays free of a browser dependency.
- Fail-open and explicit: any error returns a plain failure message rather than
  raising into the reply loop.
