mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat(spotify): consolidate tools (9→7), add spotify skill, surface in hermes setup (#15154)
Three quality improvements on top of #15121 / #15130 / #15135: 1. Tool consolidation (9 → 7) - spotify_saved_tracks + spotify_saved_albums → spotify_library with kind='tracks'|'albums'. Handler code was ~90 percent identical across the two old tools; the merge is a behavioral no-op. - spotify_activity dropped. Its 'now_playing' action was a duplicate of spotify_playback.get_currently_playing (both return identical 204/empty payloads). Its 'recently_played' action moves onto spotify_playback as a new action — history belongs adjacent to live state. - Net: each API call ships 2 fewer tool schemas when the Spotify toolset is enabled, and the action surface is more discoverable (everything playback-related is on one tool). 2. Spotify skill (skills/media/spotify/SKILL.md) Teaches the agent canonical usage patterns so common requests don't balloon into 4+ tool calls: - 'play X' = one search, then play by URI (not search + scan + describe + play) - 'what's playing' = single get_currently_playing (no preflight get_state chain) - Don't retry on '403 Premium required' or '403 No active device' — both require user action - URI/URL/bare-ID format normalization - Full failure-mode reference for 204/401/403/429 3. Surfaced in 'hermes setup' tool status Adds 'Spotify (PKCE OAuth)' to the tool status list when auth.json has a Spotify access/refresh token. Matches the homeassistant pattern but reads from auth.json (OAuth-based) rather than env vars. Docs updated to reflect the new 7-tool surface, and mention the companion skill in the 'Using it' section. Tests: 54 passing (client 22, auth 15, tools_config 35 — 18 = 54 after renaming/replacing the spotify_activity tests with library + recently_played coverage). Docusaurus build clean.
This commit is contained in:
parent
9d1b277e1d
commit
e5d41f05d4
6 changed files with 254 additions and 127 deletions
|
|
@ -64,7 +64,7 @@ Shows whether tokens are present and when the access token expires. Refresh is a
|
|||
|
||||
## Using it
|
||||
|
||||
Once logged in, the agent has access to 9 Spotify tools. You talk to the agent naturally — it picks the right tool and action.
|
||||
Once logged in, the agent has access to 7 Spotify tools. You talk to the agent naturally — it picks the right tool and action. For the best behavior, the agent loads a companion skill that teaches canonical usage patterns (single-search-then-play, when not to preflight `get_state`, etc.).
|
||||
|
||||
```
|
||||
> play some miles davis
|
||||
|
|
@ -82,12 +82,12 @@ Once logged in, the agent has access to 9 Spotify tools. You talk to the agent n
|
|||
All playback-mutating actions accept an optional `device_id` to target a specific device. If omitted, Spotify uses the currently active device.
|
||||
|
||||
#### `spotify_playback`
|
||||
Control and inspect playback.
|
||||
Control and inspect playback, plus fetch recently played history.
|
||||
|
||||
| Action | Purpose | Premium? |
|
||||
|--------|---------|----------|
|
||||
| `get_state` | Full playback state (track, device, progress, shuffle/repeat) | No |
|
||||
| `get_currently_playing` | Just the current track | No |
|
||||
| `get_currently_playing` | Just the current track (returns empty on 204 — see below) | No |
|
||||
| `play` | Start/resume playback. Optional: `context_uri`, `uris`, `offset`, `position_ms` | Yes |
|
||||
| `pause` | Pause playback | Yes |
|
||||
| `next` / `previous` | Skip track | Yes |
|
||||
|
|
@ -95,6 +95,7 @@ Control and inspect playback.
|
|||
| `set_repeat` | `state` = `track` / `context` / `off` | Yes |
|
||||
| `set_shuffle` | `state` = `true` / `false` | Yes |
|
||||
| `set_volume` | `volume_percent` = 0-100 | Yes |
|
||||
| `recently_played` | Last played tracks. Optional `limit`, `before`, `after` (Unix ms) | No |
|
||||
|
||||
#### `spotify_devices`
|
||||
| Action | Purpose |
|
||||
|
|
@ -127,18 +128,16 @@ Search the catalog. `query` is required. Optional: `types` (array of `track` / `
|
|||
| `get` | Album metadata | `album_id` |
|
||||
| `tracks` | Album track list | `album_id` |
|
||||
|
||||
#### `spotify_saved_tracks` / `spotify_saved_albums`
|
||||
#### `spotify_library`
|
||||
Unified access to saved tracks and saved albums. Pick the collection with the `kind` arg.
|
||||
|
||||
| Action | Purpose |
|
||||
|--------|---------|
|
||||
| `list` | Paginated library listing |
|
||||
| `save` | Add `ids` / `uris` to library |
|
||||
| `remove` | Remove `ids` / `uris` from library |
|
||||
|
||||
#### `spotify_activity`
|
||||
| Action | Purpose | Premium? |
|
||||
|--------|---------|----------|
|
||||
| `now_playing` | Currently playing (returns empty on 204 — see below) | No |
|
||||
| `recently_played` | Last played tracks. Optional `limit`, `before`, `after` (Unix ms) | No |
|
||||
Required: `kind` = `tracks` or `albums`, plus `action`.
|
||||
|
||||
### Feature matrix: Free vs Premium
|
||||
|
||||
|
|
@ -147,14 +146,12 @@ Read-only tools work on Free accounts. Anything that mutates playback or the que
|
|||
| Works on Free | Premium required |
|
||||
|---------------|------------------|
|
||||
| `spotify_search` (all) | `spotify_playback` — play, pause, next, previous, seek, set_repeat, set_shuffle, set_volume |
|
||||
| `spotify_playback` — get_state, get_currently_playing | `spotify_queue` — add |
|
||||
| `spotify_playback` — get_state, get_currently_playing, recently_played | `spotify_queue` — add |
|
||||
| `spotify_devices` — list | `spotify_devices` — transfer |
|
||||
| `spotify_queue` — get | |
|
||||
| `spotify_playlists` (all) | |
|
||||
| `spotify_albums` (all) | |
|
||||
| `spotify_saved_tracks` (all) | |
|
||||
| `spotify_saved_albums` (all) | |
|
||||
| `spotify_activity` (all) | |
|
||||
| `spotify_library` (all) | |
|
||||
|
||||
## Sign out
|
||||
|
||||
|
|
@ -172,7 +169,7 @@ To revoke the app on Spotify's side, visit [Apps connected to your account](http
|
|||
|
||||
**`403 Forbidden — Premium required`** — You're on a Free account trying to use a playback-mutating action. See the feature matrix above.
|
||||
|
||||
**`204 No Content` on `now_playing`** — nothing is currently playing on any device. This is Spotify's normal response, not an error; Hermes surfaces it as an explanatory empty result.
|
||||
**`204 No Content` on `get_currently_playing`** — nothing is currently playing on any device. This is Spotify's normal response, not an error; Hermes surfaces it as an explanatory empty result (`is_playing: false`).
|
||||
|
||||
**`INVALID_CLIENT: Invalid redirect URI`** — the redirect URI in your Spotify app settings doesn't match what Hermes is using. The default is `http://127.0.0.1:43827/spotify/callback`. Either add that to your app's allowed redirect URIs, or set `HERMES_SPOTIFY_REDIRECT_URI` in `~/.hermes/.env` to whatever you registered.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue