Repository navigation
fix(bot): strip fan-upload prefixes, reduce same-artist flooding in autoplay - #580
Conversation
- strip [K-POP IN PUBLIC], [Fancam], [MPD*], [4K*fps], Korean parentheticals from titles so same-song variants normalize alike - same-artist-as-current penalty: -0.35 → -0.75 - recentArtists penalty: -0.25 → -0.45 - recentArtists uses full session history (not just 3 seeds)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 13 minutes and 36 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughReworked recommendation scoring and queue replenishment: Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/bot/src/utils/music/queueManipulation.ts`:
- Line 362: Normalize artist identities before comparisons: create or use a
helper (e.g., normalizeArtistName) that lowercases, strips common noise tokens
like "vevo", "- topic", "topic", punctuation and extra whitespace, and collapses
non-alphanumeric differences; apply this normalization when building
recentArtists in buildRecentArtists(currentTrack, allHistoryTracks) and when
comparing track.author (the places that currently use author.toLowerCase(),
including the same-artist and recent-artist penalty logic around the existing
comparison block) so variants like "BIGBANG - Topic", "BIGBANGVEVO", and
"BIGBANG" are treated as the same artist for penalty calculations.
In `@packages/bot/src/utils/music/searchQueryCleaner.ts`:
- Around line 15-17: The current regexes in cleanSearchQuery() remove any
non-ASCII bracketed segments (/\([^\x00-\x7F]+\)/g and /\[[^\x00-\x7F]+\]/g)
which strips useful localized aliases; change the logic to only remove bracketed
segments when they are CJK-specific or clearly duplicate a romanized title:
replace those broad patterns with Unicode-aware checks (use Unicode property
escapes for CJK: Hangul/Hiragana/Katakana/Han) such as matching only bracket
contents that are CJK characters (e.g. use
\p{Script=Hangul}|\p{Script=Hiragana}|\p{Script=Katakana}|\p{Script=Han} with
the u flag), and/or conditionally remove the bracketed segment only if the rest
of the title contains a Roman/ASCII title (check for /[A-Za-z0-9]/ outside the
brackets) before performing the replacement in cleanSearchQuery().
- Line 94: The regex literal /\[(?:4k|hd|uhd)[\s\d+fps[^\]]*\]/gi in
searchQueryCleaner.ts is malformed (it accidentally opens a character class
mid-pattern), so tags like "[4K 60FPS FANCAM]" aren't matched; replace that
pattern with a corrected one such as /\[(?:4k|hd|uhd)[^\]]*\]/gi in the same
place (the regex used to strip 4K/HD/UHD bracketed tags inside the
searchQueryCleaner logic) so any content following the prefix up to the closing
bracket is removed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2bd87fe5-4ac0-4fd9-9846-2890b77f8e95
📒 Files selected for processing (2)
packages/bot/src/utils/music/queueManipulation.tspackages/bot/src/utils/music/searchQueryCleaner.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: SonarCloud Scan
- GitHub Check: Quality Gates
| }, | ||
| }) | ||
| const recentArtists = buildRecentArtists(currentTrack, historyTracks) | ||
| const recentArtists = buildRecentArtists(currentTrack, allHistoryTracks) |
There was a problem hiding this comment.
Normalize artist identities before applying these stronger penalties.
Line 362 makes recentArtists larger, but Lines 1355-1365 still compare raw author.toLowerCase() strings. Variants like BIGBANG - Topic, BIGBANGVEVO, and BIGBANG will still bypass both the same-artist and recent-artist penalties, which means the flooding this PR is targeting can still reappear across sources.
Proposed fix
+function normalizeArtistKey(author?: string): string {
+ return normalizeText(author ? cleanAuthor(author) : '')
+}
+
function buildRecentArtists(
currentTrack: Track,
historyTracks: Track[],
): Set<string> {
return new Set<string>(
[currentTrack.author, ...historyTracks.map((track) => track.author)]
.filter(Boolean)
- .map((artist) => artist.toLowerCase()),
+ .map((artist) => normalizeArtistKey(artist)),
)
}- const currentArtist = currentTrack.author.toLowerCase()
- const candidateArtist = candidate.author.toLowerCase()
- const candidateArtistKey = normalizeText(cleanAuthor(candidate.author))
+ const currentArtistKey = normalizeArtistKey(currentTrack.author)
+ const candidateArtistKey = normalizeArtistKey(candidate.author)
@@
- if (candidateArtist === currentArtist) {
+ if (candidateArtistKey === currentArtistKey) {
score -= 0.75
reasons.push('same artist as current')
- } else if (!recentArtists.has(candidateArtist)) {
+ } else if (!recentArtists.has(candidateArtistKey)) {
score += 0.15
reasons.push('session novelty')
} else {
reasons.push('fresh artist rotation')
}
- if (recentArtists.has(candidateArtist)) {
+ if (recentArtists.has(candidateArtistKey)) {
score -= 0.45
}Also applies to: 1355-1365
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/bot/src/utils/music/queueManipulation.ts` at line 362, Normalize
artist identities before comparisons: create or use a helper (e.g.,
normalizeArtistName) that lowercases, strips common noise tokens like "vevo", "-
topic", "topic", punctuation and extra whitespace, and collapses
non-alphanumeric differences; apply this normalization when building
recentArtists in buildRecentArtists(currentTrack, allHistoryTracks) and when
comparing track.author (the places that currently use author.toLowerCase(),
including the same-artist and recent-artist penalty logic around the existing
comparison block) so variants like "BIGBANG - Topic", "BIGBANGVEVO", and
"BIGBANG" are treated as the same artist for penalty calculations.
| // Korean/CJK parenthetical duplicates: "(뱅뱅뱅)" when title already has English equivalent | ||
| /\([^\x00-\x7F]+\)/g, | ||
| /\[[^\x00-\x7F]+\]/g, |
There was a problem hiding this comment.
Avoid stripping every non-ASCII bracketed segment here.
Lines 16-17 are much broader than the stated “duplicate Korean/CJK alias” case: they remove any all-non-ASCII parenthetical/bracketed text. That means cleanSearchQuery() now drops useful localized aliases from titles like Song (Русский) or Track [العربية], which can make downstream search less precise. Please gate this on an existing Romanized title outside the brackets, or narrow the match to the specific duplicate forms you actually want to collapse.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/bot/src/utils/music/searchQueryCleaner.ts` around lines 15 - 17, The
current regexes in cleanSearchQuery() remove any non-ASCII bracketed segments
(/\([^\x00-\x7F]+\)/g and /\[[^\x00-\x7F]+\]/g) which strips useful localized
aliases; change the logic to only remove bracketed segments when they are
CJK-specific or clearly duplicate a romanized title: replace those broad
patterns with Unicode-aware checks (use Unicode property escapes for CJK:
Hangul/Hiragana/Katakana/Han) such as matching only bracket contents that are
CJK characters (e.g. use
\p{Script=Hangul}|\p{Script=Hiragana}|\p{Script=Katakana}|\p{Script=Han} with
the u flag), and/or conditionally remove the bracketed segment only if the rest
of the title contains a Roman/ASCII title (check for /[A-Za-z0-9]/ outside the
brackets) before performing the replacement in cleanSearchQuery().
| /\[mpd[^\]]*\]/gi, | ||
| /\[color\s+coded[^\]]*\]/gi, | ||
| /\[color-coded[^\]]*\]/gi, | ||
| /\[(?:4k|hd|uhd)[\s\d+fps[^\]]*\]/gi, |
There was a problem hiding this comment.
Fix the 4K/HD/UHD bracket regex.
Line 94 accidentally turns the post-prefix part into a character class, so tags such as [4K 60FPS FANCAM] or [UHD PERFORMANCE] are not stripped unless every character after 4K/HD/UHD is one of whitespace, digits, or f/p/s. That leaves many fan-upload variants with distinct normalized keys.
Proposed fix
- /\[(?:4k|hd|uhd)[\s\d+fps[^\]]*\]/gi,
+ /\[(?:4k|hd|uhd)[^\]]*\]/gi,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /\[(?:4k|hd|uhd)[\s\d+fps[^\]]*\]/gi, | |
| /\[(?:4k|hd|uhd)[^\]]*\]/gi, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/bot/src/utils/music/searchQueryCleaner.ts` at line 94, The regex
literal /\[(?:4k|hd|uhd)[\s\d+fps[^\]]*\]/gi in searchQueryCleaner.ts is
malformed (it accidentally opens a character class mid-pattern), so tags like
"[4K 60FPS FANCAM]" aren't matched; replace that pattern with a corrected one
such as /\[(?:4k|hd|uhd)[^\]]*\]/gi in the same place (the regex used to strip
4K/HD/UHD bracketed tags inside the searchQueryCleaner logic) so any content
following the prefix up to the closing bracket is removed.
Artist penalties blocked same-artist songs entirely. The normalizeTrackKey + fan-upload NOISE_PATTERNS already prevent exact song repeats. Only retain +0.15 novelty boost for diversity.
|
Size Change: 0 B Total Size: 325 kB ℹ️ View Unchanged
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/bot/src/utils/music/queueManipulation.ts (1)
1311-1404:⚠️ Potential issue | 🟠 MajorRestore the current/recent-artist penalties.
Line 1354 now only withholds the novelty bonus for recent artists. The explicit same-artist-as-current penalty and the general recent-artist fatigue penalty are gone, so
similar/popularmode can still keep picking the current artist whenever preferred/liked/history boosts are present. That undercuts the flood-control goal of this change.Suggested fix
const currentArtist = currentTrack.author.toLowerCase() const candidateArtist = candidate.author.toLowerCase() @@ - if (!recentArtists.has(candidateArtist)) { + if (candidateArtist === currentArtist) { + score -= 0.75 + reasons.push('same artist as current') + } else if (!recentArtists.has(candidateArtist)) { score += 0.15 reasons.push('session novelty') + } else { + score -= 0.45 } @@ - if (recentArtists.has(candidateArtist)) { + if (recentArtists.has(candidateArtist)) { score -= 0.2 }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/bot/src/utils/music/queueManipulation.ts` around lines 1311 - 1404, Reintroduce the missing artist-penalties by modifying the scoring in the same scope that computes novelty: after the novelty bonus using recentArtists and the variables currentArtist/candidateArtist, subtract a penalty when candidateArtist === currentArtist (e.g., score -= 0.25 and reasons.push('same artist penalty')) and also apply a smaller general recent-artist fatigue penalty when recentArtists.has(candidateArtist) (e.g., score -= 0.1 and reasons.push('recent artist fatigue')); keep these adjustments separate from the autoplayMode === 'discover' branch so preferred/liked/history boosts cannot repeatedly bypass flood-control, and update the reasons array and score consistently where currentArtist, candidateArtist, recentArtists, score and reasons are used.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@packages/bot/src/utils/music/queueManipulation.ts`:
- Around line 1311-1404: Reintroduce the missing artist-penalties by modifying
the scoring in the same scope that computes novelty: after the novelty bonus
using recentArtists and the variables currentArtist/candidateArtist, subtract a
penalty when candidateArtist === currentArtist (e.g., score -= 0.25 and
reasons.push('same artist penalty')) and also apply a smaller general
recent-artist fatigue penalty when recentArtists.has(candidateArtist) (e.g.,
score -= 0.1 and reasons.push('recent artist fatigue')); keep these adjustments
separate from the autoplayMode === 'discover' branch so preferred/liked/history
boosts cannot repeatedly bypass flood-control, and update the reasons array and
score consistently where currentArtist, candidateArtist, recentArtists, score
and reasons are used.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e0b1c642-44a7-4315-a2f9-1ae64db4c4b8
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
package.jsonpackages/backend/package.jsonpackages/bot/package.jsonpackages/bot/src/utils/music/queueManipulation.tspackages/frontend/package.jsonpackages/shared/package.json
✅ Files skipped from review due to trivial changes (5)
- packages/backend/package.json
- packages/shared/package.json
- package.json
- packages/bot/package.json
- packages/frontend/package.json
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: SonarCloud Scan
- GitHub Check: compressed-size
- GitHub Check: Quality Gates
|
…utoplay (#580) * fix(bot): strip fan-upload prefixes, reduce same-artist flooding - strip [K-POP IN PUBLIC], [Fancam], [MPD*], [4K*fps], Korean parentheticals from titles so same-song variants normalize alike - same-artist-as-current penalty: -0.35 → -0.75 - recentArtists penalty: -0.25 → -0.45 - recentArtists uses full session history (not just 3 seeds) * chore: bump version to 2.6.98 * fix(bot): remove artist blocking, keep only song dedup Artist penalties blocked same-artist songs entirely. The normalizeTrackKey + fan-upload NOISE_PATTERNS already prevent exact song repeats. Only retain +0.15 novelty boost for diversity. * test(bot): cover scoring branches for implicit feedback and duration * test(bot): fix familiar-artist test to use queue history not redis mock



Problem (from production logs)
BIGBANG "Bang Bang Bang" appeared 20+ times in queue because:
[K-POP IN PUBLIC | ONE TAKE],[Fancam],[MPD직캠],[4K 60FPS]) — each normalized to a completely different key, passing all dedup checksrecentArtistswas built from only 3 history seeds, so BIGBANG's fatigue penalty expired quicklyFixes
searchQueryCleaner.ts— fan-upload NOISE_PATTERNS[K-POP IN PUBLIC | ONE TAKE],[KPOP IN PUBLIC],[Fancam ...],[MPD*],[Color Coded*],[4K*FPS],[Dance Cover by X],[Stage Mix],[Multi](뱅뱅뱅)when title already has Roman equivalentM/VandMVmarkersbigbangbangbang::bigbangqueueManipulation.ts— scoringrecentArtistsfatigue penalty: -0.25 → -0.45recentArtistsnow built from full session history (all tracks, not just the 3 seed tracks) — an artist played 10 songs ago still gets the fatigue penaltySummary by CodeRabbit