Spotify: read-only Verbindungstest-Skript (Toolset/Login/Live-API), analog zum Auth-Skript
Prueft direkt in Hermes' eigenem Code (get_auth_status, _get_platform_tools, SpotifyClient), ob Toolset aktiviert, Login vorhanden und ein echter GET /me/player/devices erfolgreich ist -- ohne Umweg ueber Claude/Proxy, da LLM-Textantworten wie 'nicht verbunden/aktiv' kein verlaesslicher Diagnosewert sind.
This commit is contained in:
@@ -294,6 +294,32 @@ nennen. Falls es weiter hakt: `docker logs hermes-proxy --tail 100 -f`
|
||||
waehrend der Reproduktion pruefen ob `--safe-mode` tatsaechlich im
|
||||
gestarteten Prozess ankam (`docker exec -it hermes-proxy ps aux | grep claude`).
|
||||
|
||||
### Verbindungstest ohne Chat/Claude (`spotify_test_connection.py`)
|
||||
|
||||
Wenn Claude im Dashboard-Chat was sagt wie "Spotify-Tools sind zwar
|
||||
gelistet, aber nicht verbunden/aktiv" ist unklar OB das stimmt oder ob
|
||||
Claude nur raet — eine LLM-Textantwort ist kein verlaesslicher
|
||||
Diagnosewert. `scripts/spotify_test_connection.py` prueft stattdessen
|
||||
direkt in Hermes' eigenem Code (denselben Funktionen, die der echte
|
||||
Tool-Dispatch benutzt), read-only, ohne irgendwas zu veraendern:
|
||||
|
||||
1. Ist das Toolset `spotify` ueber `hermes tools` fuer irgendeine
|
||||
Plattform aktiviert? (`~/.hermes/config.yaml` -> `platform_toolsets`)
|
||||
2. Ist Spotify eingeloggt? (`~/.hermes/auth.json` -> `providers.spotify`)
|
||||
3. Funktioniert ein ECHTER API-Call mit dem gespeicherten Token
|
||||
(`GET /me/player/devices`, inkl. Auto-Refresh falls abgelaufen)?
|
||||
|
||||
```bash
|
||||
docker cp scripts/spotify_test_connection.py hermes-agent:/tmp/spotify_test_connection.py
|
||||
docker exec -it hermes-agent python3 /tmp/spotify_test_connection.py
|
||||
```
|
||||
|
||||
Sind alle drei Punkte gruen und der Chat sagt trotzdem "kenn ich nicht" /
|
||||
"nicht verbunden", liegt's am Proxy bzw. am System-Prompt (siehe Abschnitt
|
||||
oben), nicht an Spotify selbst — dann `docker logs hermes-proxy` waehrend
|
||||
der Reproduktion pruefen. Gleiches Nutzungsmuster wie
|
||||
`scripts/spotify_manual_auth.py` (Login-Skript weiter oben).
|
||||
|
||||
## Mobiler Client (Android)?
|
||||
|
||||
Zwei GRUNDVERSCHIEDENE Richtungen, nicht verwechseln:
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Spotify-Verbindungstest fuer Hermes -- prueft in drei Schritten, OHNE den
|
||||
Umweg ueber Claude/den Proxy, ob Spotify aus dem Chat heraus wirklich
|
||||
funktionieren sollte.
|
||||
|
||||
Hintergrund: Wenn Claude im Dashboard-Chat sowas sagt wie "Spotify-Tools
|
||||
sind zwar in meiner Werkzeugliste beschrieben, aber in dieser Session
|
||||
aktuell nicht verbunden/aktiv", ist unklar OB das stimmt oder ob Claude nur
|
||||
raet -- Text-Antworten vom LLM sind kein verlaesslicher Diagnosewert. Dieses
|
||||
Skript ruft dieselben Hermes-internen Funktionen direkt auf, die auch beim
|
||||
echten Tool-Dispatch benutzt werden (siehe plugins/spotify/tools.py
|
||||
_check_spotify_available und plugins/spotify/client.py SpotifyClient):
|
||||
|
||||
1. Toolset "spotify" ueber `hermes tools` aktiviert? (pro Plattform,
|
||||
~/.hermes/config.yaml -> platform_toolsets)
|
||||
2. Bei Spotify eingeloggt? (~/.hermes/auth.json -> providers.spotify)
|
||||
3. Funktioniert ein ECHTER API-Call mit dem gespeicherten Token (inkl.
|
||||
Auto-Refresh falls abgelaufen)? Ruft GET /me/player/devices auf --
|
||||
harmlos, read-only, keine Wiedergabe wird veraendert.
|
||||
|
||||
Nutzung (im hermes-agent-Container, wo hermes_cli installiert ist):
|
||||
docker cp scripts/spotify_test_connection.py hermes-agent:/tmp/spotify_test_connection.py
|
||||
docker exec -it hermes-agent python3 /tmp/spotify_test_connection.py
|
||||
|
||||
Reiner Read-Only-Diagnose-Check, veraendert nichts. Fuer den Login selbst
|
||||
siehe scripts/spotify_manual_auth.py (gleiches Nutzungsmuster).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
from hermes_cli.auth import get_auth_status
|
||||
except ImportError as exc: # pragma: no cover
|
||||
sys.exit(
|
||||
"Konnte hermes_cli.auth nicht importieren -- Skript muss INNERHALB "
|
||||
f"des hermes-agent-Containers laufen (python3 dort). Fehler: {exc}"
|
||||
)
|
||||
|
||||
try:
|
||||
from hermes_cli.config import load_config_readonly
|
||||
from hermes_cli.tools_config import _get_platform_tools, PLATFORMS
|
||||
except ImportError as exc: # pragma: no cover
|
||||
sys.exit(f"Konnte hermes_cli.tools_config/config nicht importieren: {exc}")
|
||||
|
||||
try:
|
||||
from plugins.spotify.client import (
|
||||
SpotifyAPIError,
|
||||
SpotifyAuthRequiredError,
|
||||
SpotifyClient,
|
||||
SpotifyError,
|
||||
)
|
||||
except ImportError as exc: # pragma: no cover
|
||||
sys.exit(f"Konnte plugins.spotify.client nicht importieren: {exc}")
|
||||
|
||||
|
||||
def _bar(title: str) -> None:
|
||||
print()
|
||||
print("=" * 78)
|
||||
print(title)
|
||||
print("=" * 78)
|
||||
|
||||
|
||||
def check_auth() -> bool:
|
||||
_bar("1) Login-Status (~/.hermes/auth.json -> providers.spotify)")
|
||||
status = get_auth_status("spotify")
|
||||
logged_in = bool(status.get("logged_in"))
|
||||
print(f" logged_in: {logged_in}")
|
||||
print(f" auth_type: {status.get('auth_type')}")
|
||||
print(f" client_id: {status.get('client_id')}")
|
||||
print(f" redirect_uri: {status.get('redirect_uri')}")
|
||||
print(f" scope: {status.get('scope')}")
|
||||
print(f" expires_at: {status.get('expires_at')}")
|
||||
print(f" has_refresh_token: {status.get('has_refresh_token')}")
|
||||
if not logged_in:
|
||||
print()
|
||||
print(" -> NICHT eingeloggt. `python3 spotify_manual_auth.py` ausfuehren")
|
||||
print(" (oder `hermes auth spotify`, falls SSH-Port-Forward moeglich ist).")
|
||||
return logged_in
|
||||
|
||||
|
||||
def check_toolsets() -> bool:
|
||||
_bar("2) Toolset 'spotify' aktiviert? (hermes tools, pro Plattform)")
|
||||
config = load_config_readonly()
|
||||
any_enabled = False
|
||||
for platform_key, info in sorted(PLATFORMS.items()):
|
||||
try:
|
||||
enabled = _get_platform_tools(config, platform_key)
|
||||
except Exception as exc:
|
||||
print(f" {platform_key:14s} -> Fehler beim Aufloesen: {exc}")
|
||||
continue
|
||||
is_on = "spotify" in enabled
|
||||
any_enabled = any_enabled or is_on
|
||||
marker = "AN " if is_on else "aus"
|
||||
label = info.get("label", platform_key) if isinstance(info, dict) else platform_key
|
||||
print(f" [{marker}] {platform_key:14s} ({label})")
|
||||
if not any_enabled:
|
||||
print()
|
||||
print(" -> Fuer KEINE Plattform aktiviert. Im Container:")
|
||||
print(" `hermes tools` -> zu Spotify runterscrollen -> Leertaste -> mit 's' speichern.")
|
||||
return any_enabled
|
||||
|
||||
|
||||
def check_live_call() -> bool:
|
||||
_bar("3) Echter Live-API-Call (GET /me/player/devices, read-only)")
|
||||
try:
|
||||
client = SpotifyClient()
|
||||
devices = client.get_devices()
|
||||
except SpotifyAuthRequiredError as exc:
|
||||
print(f" FEHLER (Auth erforderlich): {exc}")
|
||||
return False
|
||||
except SpotifyAPIError as exc:
|
||||
print(f" FEHLER (Spotify-API, status={exc.status_code}): {exc}")
|
||||
return False
|
||||
except SpotifyError as exc:
|
||||
print(f" FEHLER: {exc}")
|
||||
return False
|
||||
except Exception as exc: # pragma: no cover
|
||||
print(f" UNERWARTETER FEHLER ({type(exc).__name__}): {exc}")
|
||||
return False
|
||||
|
||||
items = (devices or {}).get("devices", []) if isinstance(devices, dict) else []
|
||||
if not items:
|
||||
print(" API-Call erfolgreich, aber KEINE Geraete gemeldet.")
|
||||
print(" -> Spotify-App auf dem Zielgeraet (Handy/PC) kurz oeffnen, damit es")
|
||||
print(" bei Spotify Connect als aktiv gemeldet wird, dann nochmal testen.")
|
||||
else:
|
||||
print(f" API-Call erfolgreich, {len(items)} Geraet(e) gefunden:")
|
||||
for d in items:
|
||||
active = "aktiv" if d.get("is_active") else "inaktiv"
|
||||
print(f" - {d.get('name')} ({d.get('type')}, {active}, vol={d.get('volume_percent')}%)")
|
||||
return True
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ok_auth = check_auth()
|
||||
ok_tools = check_toolsets()
|
||||
ok_live = check_live_call() if ok_auth else False
|
||||
|
||||
_bar("Zusammenfassung")
|
||||
print(f" 1) Eingeloggt: {'OK' if ok_auth else 'FEHLT'}")
|
||||
print(f" 2) Toolset aktiviert: {'OK' if ok_tools else 'FEHLT'}")
|
||||
print(f" 3) Live-API erreichbar: {'OK' if ok_live else 'FEHLT/UEBERSPRUNGEN'}")
|
||||
print()
|
||||
if ok_auth and ok_tools and ok_live:
|
||||
print("Alles gruen -- Spotify sollte im Chat funktionieren. Kommt trotzdem")
|
||||
print("'kenn ich nicht'/'nicht verbunden', liegt's am Proxy bzw. System-Prompt")
|
||||
print("(z.B. Claude nutzt eigene Connectors statt der injizierten Tools),")
|
||||
print("nicht an Spotify selbst -- dann bitte docker logs hermes-proxy pruefen.")
|
||||
else:
|
||||
print("Siehe die '->'-Hinweise oben fuer den jeweils naechsten Schritt.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user