diff --git a/backend/app/services/gallery_service.py b/backend/app/services/gallery_service.py index ca2a7df..d4e923b 100644 --- a/backend/app/services/gallery_service.py +++ b/backend/app/services/gallery_service.py @@ -289,7 +289,7 @@ def _gallery_images(rows, artists: dict[int, dict]) -> list[GalleryImage]: ] -def _diversify_similar(src, rows, limit, *, dup_threshold=6, lam=0.55): +def _diversify_similar(src, rows, limit, *, dup_threshold=8, lam=0.40): """Trim a nearest-cosine candidate pool down to `limit` diverse picks. 1. pHash collapse: drop any candidate whose perceptual hash is within @@ -300,6 +300,11 @@ def _diversify_similar(src, rows, limit, *, dup_threshold=6, lam=0.55): the most relevant up top but pushes the selection to SPAN clusters instead of returning 40 variations of one image. + `lam` is the variance dial: lower = weight the diversity penalty harder, so + the rail reaches further across clusters (operator wanted MORE variance, + 2026-07-01 — dropped 0.55→0.40, dup 6→8, paired with a wider pool in + `similar()`). + Falls back to nearest-order (`rows[:limit]`) on any failure or a small pool. """ if len(rows) <= 1: @@ -658,8 +663,10 @@ class GalleryService: return [] # Over-fetch so diversification has clusters to spread across — without a - # wide pool there's nothing but the near-dupes to choose from. - pool_n = min(200, max(limit * 5, 60)) + # wide pool there's nothing but the near-dupes to choose from. Widened + # (5×→8×, cap 200→400) so the stronger MMR has genuinely distinct + # neighbourhoods to reach into for more variance (operator, 2026-07-01). + pool_n = min(400, max(limit * 8, 100)) distance = ImageRecord.siglip_embedding.cosine_distance(src.siglip_embedding) eff = _effective_date_col() stmt = select(ImageRecord, Post.post_date, eff.label("eff"))