feat(explore): reach dial to escape dense clusters + anti-revisit (#1476)
The Explore walk got stuck in dense signatures — neighbours all too similar, so forward-arrow couldn't escape and Random was the only exit. Root cause: MMR only diversifies WITHIN the nearest ~400 pool; in a dense cluster that whole pool is near-identical, so there's no escape route in it. - gallery_service.similar(reach=0.0, exclude_ids=None): reach>0 widens the pool (cap 400→1000) and _reach_sample strides across an outward-growing distance span so the set handed to MMR spans near→mid-far (guaranteed escape routes), not just the tight cluster. exclude_ids drops already-walked images. Gallery 'more like this' (reach=0) is unchanged. - api/gallery similar: parse reach + exclude_ids. - explore store: default reach 0.4 (auto-diversifies without touching the dial), pass the breadcrumb as exclude_ids, setReach action. - ExploreView: a Near↔Far reach slider in the trail. - tests: _reach_sample math (deeper ranks with higher reach, near kept); similar exclude_ids drops walked + reach path runs clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -170,6 +170,23 @@ async def test_similar_respects_limit(db):
|
||||
assert len(res) == 2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_similar_exclude_ids_drops_walked(db):
|
||||
"""Explore passes its breadcrumb as exclude_ids so already-walked images
|
||||
aren't re-served as neighbours (#1476). reach>0 runs cleanly too (small pool
|
||||
→ the sampler passes through)."""
|
||||
src = await _img(db, 1, _vec(1, 0))
|
||||
walked = await _img(db, 2, _vec(1, 0.05))
|
||||
fresh = await _img(db, 3, _vec(1, 0.3))
|
||||
svc = GalleryService(db)
|
||||
res = await svc.similar(src.id, limit=10, exclude_ids=[walked.id])
|
||||
ids = {i.id for i in res}
|
||||
assert walked.id not in ids
|
||||
assert fresh.id in ids
|
||||
res_reach = await svc.similar(src.id, limit=10, reach=1.0)
|
||||
assert fresh.id in {i.id for i in res_reach}
|
||||
|
||||
|
||||
# --- API ---
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user