profile.embedding was being passed as str(numpy_array) which produces
scientific notation format. pgvector needs [n1,n2,...] format. Now
explicitly formats as comma-separated float list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In transformers 5.x, ClapModel.get_audio_features() returns a
BaseModelOutputWithPooling instead of a raw tensor. The 512-dim
embedding is in .pooler_output[0], not directly indexed. Added
backward-compatible extraction with hasattr check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two issues:
1. CLAP model output needed .flatten() to produce a 1-D vector for
pgvector. Without it, the nested array caused "expected ndim to be 1".
2. Worker now uses a fresh session per track instead of sharing one
across a batch, preventing PendingRollbackError cascading from one
failure to the next.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The except clause wasn't binding the exception to a variable, so
str(Exception) stored the class name "<class 'Exception'>" instead of
the actual error message. Now properly captures `as e` and stores str(e).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SQLAlchemy relationships require ForeignKey on the column definitions,
not just in the migration. Without them, mapper initialization fails.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The pyproject.toml references the package source, so src/ must be
present when pip resolves metadata.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full music recommendation pipeline: listening history capture via webhook,
Last.fm candidate discovery, iTunes preview download, CLAP audio embeddings
(512-dim), pgvector cosine similarity recommendations, playlist generation
with known/new track interleaving, and Music Assistant playback via HA.
Includes: FastAPI app, SQLAlchemy models, Alembic migrations, Docker Compose
with pgvector/pg17, status dashboard, and all API endpoints.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>