Add explore feed engine tests and docs

This commit is contained in:
thePR0M3TH3AN committed 2026-01-22 19:36:31 -05:00
1 parent 74f3e85720
commit 2025a973ca
4 files changed
+275 -2

No files matched your search

+25 -2
View File
@@ -71,6 +71,7 @@ constructed today behave exactly like the existing UI.
| `createTagPreferenceFilterStage` | Normalizes interest/disinterest tags via `normalizeHashtag`, drops videos that match disinterests, and (by default) filters out videos that do not match interest tags. Set `enforceInterests: false` to keep items even when they lack interest tags. |
| `createDisinterestFilterStage` | Normalizes tag preferences via `normalizeHashtag` and drops videos that match disinterests without excluding items that lack interest tags (useful for Explore-style feeds). |
| `createWatchHistorySuppressionStage` | Invokes feed-provided hooks to optionally suppress watched items. Useful for per-feed watch history preferences. |
| `createExploreScorerStage` | Computes `metadata.exploreScore` and `metadata.exploreComponents` using novelty, freshness, tag overlap, and popularity signals. Emits `addWhy()` entries for dominant positives and disinterest overlap. |
Stages receive `(items, context)` and should return the transformed list. They
can rely on `context.addWhy(...)` to annotate decisions without mutating the
@@ -79,8 +80,30 @@ items in place.
## Sorting & Decorators
`createChronologicalSorter` is the baseline sorter that orders DTOs by
`video.created_at` (newest first by default). Additional decorators can run
after sorting to attach extra metadata or inject presentation hints.
`video.created_at` (newest first by default). Explore feeds can apply
`createExploreDiversitySorter` to Maximal Marginal Relevance (MMR) re-rank
items for tag diversity while still respecting `metadata.exploreScore`.
Additional decorators can run after sorting to attach extra metadata or inject
presentation hints.
## Explore Feed Pipeline
Explore builds on the standard feed engine stages with a scoring + diversity
pass. The current Explore pipeline is:
1. `createDisinterestFilterStage` — drop disinterested tags early.
2. `createBlacklistFilterStage` — enforce NSFW/privacy/author block policies.
3. `createDedupeByRootStage` — keep the newest root version.
4. `createModerationStage` — apply moderation blur/autoplay/hide rules.
5. `createResolvePostedAtStage` — hydrate `rootCreatedAt` timestamps.
6. `createExploreScorerStage` — calculate explore scores/components.
7. `createExploreDiversitySorter` — re-rank by MMR to improve tag variety.
Explore expects additional runtime inputs:
- `tagPreferences` — `{ interests, disinterests }` arrays for preference-aware scoring.
- `watchHistoryTagCounts` — map/object of tag counts for novelty + history similarity.
- `exploreTagIdf` — IDF weights for tag vectors (Map or object).
## Configuration Hooks
+5
View File
@@ -36,6 +36,9 @@ Once the feed engine is involved, additional filtering happens inside
- Invokes `nostrService.shouldIncludeVideo` again within the pipeline so that
blacklist/author-block/NSFW/privacy gates remain enforced for feed-sourced
items.
- **`createDisinterestFilterStage()`**
- Drops videos that match a viewer’s disinterested tags. Explore uses this
stage to remove “not interested” matches before scoring and reranking.
- **`hasDisinterestedTag(video, tagPreferences)`**
- Interprets **tag disinterest** preferences, returning `true` when a video’s
tags match a user’s “not interested” preferences.
@@ -73,6 +76,8 @@ videos that have already survived the filtering stages above.
3. **Sorter**
- The feed’s configured sorter (for example, chronological or relevance)
orders the surviving entries.
- Explore uses `createExploreDiversitySorter` to re-rank scored items so
top results include a broader spread of tags.
4. **Render**
- The feed engine hands the final list to `VideoListView`, which renders
grids in `views/most-recent-videos.html`, `views/subscriptions.html`, and