Yes, I was able to get this working. Here’s the final version of it that I used, you can see I added copious comments to try to nudge it in the right direction:
- spec:
name: play_music
description: >
Use this to construct the input to play_music function Search for
and play some music. If the user wants a song, then use only song and
artist. If the user wants an album, use the album name and artist name. If
the user doesn't want a song or an album, probably they are looking for a
playlist, so use only playlist in that case. The user might also want to
just hear the top tracks from an artist, in which case use only artist.
Use category only if you are sure the user is looking for a particular "vibe"
rather than something specific.
parameters:
type: object
properties:
song_name:
type: string
description: >
The name of a song to be in the search query.
Correct any mistakes from the user, e.g. "lept it go" becomes "Let It Go".
album_name:
type: string
description: >
The name of an album to be in the search query.
Correct any user mistakes, e.g. "Chery Tee" becomes "Cherry Tree".
artist_name:
type: string
description: >
The name of a musical artist.
Correct user mistakes and complete the name if the user shortened it, e.g. "Elvis" becomes "Elvis Presley", "mbv" becomes "My Bloody Valentine", etc.
playlist_name:
type: string
description: >
The name of a playlist.
Prefer Spotify's generated playlists and Spotify's playlists in general.
category_name:
type: string
description: >
Use categories if you want something like a genre, for example,
Hip-Hop, Indie, In the car. If you don't want a random playlist with
this category, then don't set this variable. This name needs to match an exact category on Spotify
so don't set this variable unless you are very sure it will be a hit, e.g. "pop" will be a hit, "dance" will be a hit,
but for a query like "sleepy music", instead come up with an appropriate album or artist using your knowledge and search for that instead.
function:
type: script
sequence:
- service: spotcast.start
data:
limit: 20
force_playback: false
repeat: "off"
offset: 0
entity_id: media_player.<your spotify media player>
# optional - I specify a device ID here which I got from https://developer.spotify.com/documentation/web-api/reference/get-a-users-available-devices so that it always plays back from a certain device. If you don't include this, it will playback from the current Spotify source device
spotify_device_id: "<your device id>"
category: "{{ category_name | default('') }}"
search: "{% if song_name is defined %}{{ song_name }}{% endif %}{% if album_name is defined %} {{ album_name }}{% endif %}{% if artist_name is defined %} {{ artist_name }}{% endif %}{% if playlist_name is defined %} {{ playlist_name }}{% endif %}"
And I also add this to the prompt:
For the play_music function, be really smart and correct the user's query, for example, if the user asks "play some Elvis",
you should set artist_name: "Elvis Presley" since you know the user probably means Elvis Presley.
Now with all that, I can ask complex queries such as:
Play that band that always has 2D cartoons of themselves in their music videos
(plays Gorillaz)
and other such fun “smart” tasks.
Otherwise, I was having a constant problem where even a simple query e.g. “play Elvis” would result in it playing a song with a title “Elvis”, etc - lot’s of obvious mistakes, and now it is better, although YMMV.
I am still playing around with this and refining it but it is pretty fun to use already. It does have issues, both with correctness and also doing things like playing music when you did not want it to, that kind of thing.