Skip to content

fix: dedup same song across youtube title format variants - #582

Merged
LucasSantana-Dev merged 1 commit into
mainfrom
fix/autoplay-title-dedup
Apr 13, 2026
Merged

LucasSantana-Dev merged 1 commit into
mainfrom
fix/autoplay-title-dedup

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Apr 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add Brazilian/Portuguese noise patterns to NOISE_PATTERNS: (Tradução...), Legendado, (Clipe Oficial), hashtags #\S+, bare Lyrics
  • Export extractSongCore(title, author?) from searchQueryCleaner.ts — extracts the song portion from "Artist - Song" or inverted "Song - Artist" formats using the author field to disambiguate; trims secondary separators (e.g. "Halo - VERSÃO FORROZINHO" → "Halo")
  • buildExcludedKeys and isDuplicateCandidate now include a third core-title key per track, so all variants of the same song dedup correctly

Root cause

normalizeTitleOnly("Beyoncé - Halo (Tradução/Legendado)") produced "beyonchalotraduolegendado" which never matched history entry normalizeTitleOnly("Beyoncé - Halo") = "beyonchalo". Nine variants of the same Beyoncé song were added to history within minutes.

Production log evidence (before fix)

[04:20:20] Beyoncé - Halo
[04:21:15] Beyoncé - Halo (Tradução/Legendado)       ← not deduped
[04:21:15] Halo - Beyoncé (Lyrics)                   ← not deduped
[04:21:15] Beyoncé - Halo Lyrics #music #lyrics #lmc ← not deduped
[04:25:01] Beyonce - Halo (Tradução)( legendado)(Clipe Oficial) ← not deduped
[04:25:01] Beyoncé - Halo - VERSÃO FORROZINHO        ← not deduped
[04:25:04] Halo - Beyoncé - (Tradução) Legendado Lyrics ← not deduped
[04:25:04] Beyoncé - Halo (Tradução)                 ← not deduped

Test plan

  • searchQueryCleaner.spec.ts — 13 new tests for Brazilian noise patterns and extractSongCore (62 total, all passing)
  • queueManipulation.spec.ts — 77 existing tests, all passing
  • Full bot suite — 2140 tests passing

Summary by CodeRabbit

  • Bug Fixes

    • Improved music queue duplicate detection to more accurately identify duplicate songs using song core information, reducing false positives.
  • Improvements

    • Enhanced title parsing to better handle Portuguese/Brazilian YouTube metadata, including translation indicators, official clip labels, hashtags, and lyric markers, resulting in cleaner song identification.

add Brazilian noise patterns (Tradução, Legendado, Clipe Oficial, hashtags,
bare Lyrics) and extractSongCore() to identify the core song title from
artist-prefixed or inverted "Song - Artist" formats.

buildExcludedKeys and isDuplicateCandidate now also check a core-title key,
so "Beyoncé - Halo (Tradução/Legendado)", "Halo - Beyoncé (Lyrics)", and
"Beyoncé - Halo Lyrics #music" all correctly dedup against a history entry
of "Beyoncé - Halo".
@vercel

vercel Bot commented Apr 13, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lucky Ready Ready Preview, Comment Apr 13, 2026 4:41am

@coderabbitai

coderabbitai Bot commented Apr 13, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR enhances music queue duplicate detection by introducing a new extractSongCore utility function in searchQueryCleaner that extracts and normalizes the core artist-song pair from titles. The function is then integrated into queueManipulation's duplicate detection logic to provide broader exclusion matching via song-core normalization, alongside existing title and full-pair checks.

Changes

Cohort / File(s) Summary
Song Core Extraction
packages/bot/src/utils/music/searchQueryCleaner.ts
Added new extractSongCore(title, author?) function that cleans titles, splits on separators (" - ", " – ", " — "), uses optional author to disambiguate format ("Artist - Song" vs "Song - Artist"), and removes internal separators. Extended NOISE_PATTERNS to strip Portuguese/YouTube noise: hashtags, translation variants ((tradução), [tradução]), "legendado", "clipe oficial" variants, and standalone "lyrics".
Duplicate Detection Enhancement
packages/bot/src/utils/music/queueManipulation.ts
Imported extractSongCore and updated buildExcludedKeys to include normalizeText(extractSongCore(...)) as an additional duplicate/exclusion key. Modified isDuplicateCandidate to treat matches against song-core-normalized keys as duplicates, complementing existing title and full-pair checks. Minor refactoring of conditional assignments and token retrieval awaits into single-line conditions.
Test Coverage
packages/bot/src/utils/music/searchQueryCleaner.spec.ts
Added test cases for expanded cleanTitle coverage with Portuguese noise patterns (tradução variants, legendado, clipe oficial, hashtags, lyrics). Added comprehensive extractSongCore test block validating format detection ("Artist - Song" vs inverted), author matching behavior, secondary separator trimming, null handling for missing separators, and noise removal before extraction.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

bot, size/m

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: fixing deduplication by normalizing YouTube title format variants using a song-core extraction approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/autoplay-title-dedup

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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`:
- Around line 670-671: The current dedup logic only checks candidate cores
against the prebuilt exclusion set, so variants returned in the same replenish
pass (e.g., "Beyoncé - Halo" and "Halo - Beyoncé") can both be accepted; update
the selection flow in selectDiverseCandidates/upsertScoredCandidate to also
maintain a local set of core keys for the current pass (use extractSongCore and
normalizeText to derive keys, and also consider normalizeTitleOnly where
relevant) and check each candidate against both the prebuilt exclusion set and
this local currentPassKeys before accepting; when a candidate is accepted, add
its core key to currentPassKeys so subsequent candidates in the same pass are
blocked.

In `@packages/bot/src/utils/music/searchQueryCleaner.ts`:
- Around line 231-244: The current normalization in extractSongCore (norm +
cleanAuthor) strips non-ASCII letters so non-Latin artist names become empty and
overlaps() can't disambiguate; update norm to preserve Unicode letters and
numbers (use a Unicode-aware regex like excluding [^\p{L}\p{N}] with the u flag)
so authNorm, norm(left), and norm(right) retain non-Latin characters, and keep
the overlaps logic (overlaps, songPart, left, right) intact so inverted titles
for multilingual artists are correctly detected.
🪄 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: 85c41bf3-51b8-4751-bca8-2e6d5bf2eb03

📥 Commits

Reviewing files that changed from the base of the PR and between dfe63aa and 8f77fbd.

📒 Files selected for processing (3)
  • packages/bot/src/utils/music/queueManipulation.ts
  • packages/bot/src/utils/music/searchQueryCleaner.spec.ts
  • packages/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: Quality Gates
  • GitHub Check: SonarCloud Scan

Comment on lines +670 to +671
const core = extractSongCore(t.title ?? '', t.author)
if (core) keys.push(normalizeText(core))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Core-key dedup still doesn't apply between candidates picked in the same replenish pass.

These additions only compare a track against the prebuilt exclusion set. If the same search batch returns both Beyoncé - Halo and Halo - Beyoncé, they can still survive together because upsertScoredCandidate() keys by full title/author and selectDiverseCandidates() only blocks normalizeTitleOnly(...). So this fixes queue/history duplicates, but not the “two variants added together right now” case.

Also applies to: 1453-1454

🤖 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 670 - 671,
The current dedup logic only checks candidate cores against the prebuilt
exclusion set, so variants returned in the same replenish pass (e.g., "Beyoncé -
Halo" and "Halo - Beyoncé") can both be accepted; update the selection flow in
selectDiverseCandidates/upsertScoredCandidate to also maintain a local set of
core keys for the current pass (use extractSongCore and normalizeText to derive
keys, and also consider normalizeTitleOnly where relevant) and check each
candidate against both the prebuilt exclusion set and this local currentPassKeys
before accepting; when a candidate is accepted, add its core key to
currentPassKeys so subsequent candidates in the same pass are blocked.

Comment on lines +231 to +244
const norm = (s: string) =>
s.toLowerCase().replaceAll(/[^a-z0-9]+/g, '')
const authNorm = norm(cleanAuthor(author))
const overlaps = (a: string, b: string) =>
a.length >= 3 &&
b.length >= 3 &&
(a.includes(b.slice(0, 4)) || b.includes(a.slice(0, 4)))
if (overlaps(authNorm, norm(left))) {
songPart = right
} else if (overlaps(authNorm, norm(right))) {
songPart = left
} else {
songPart = right
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

extractSongCore stops disambiguating inverted titles for non-Latin artist names.

The overlap check drops every character outside [a-z0-9] before comparing author, left, and right. For artists like 아이유, 宇多田ヒカル, or Руки Вверх, both sides normalize to '', so an inverted title such as 좋은날 - 아이유 falls through to songPart = right and returns the artist instead of the song. That means the new core-key dedup still misses multilingual variants.

🤖 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 231 - 244,
The current normalization in extractSongCore (norm + cleanAuthor) strips
non-ASCII letters so non-Latin artist names become empty and overlaps() can't
disambiguate; update norm to preserve Unicode letters and numbers (use a
Unicode-aware regex like excluding [^\p{L}\p{N}] with the u flag) so authNorm,
norm(left), and norm(right) retain non-Latin characters, and keep the overlaps
logic (overlaps, songPart, left, right) intact so inverted titles for
multilingual artists are correctly detected.

@LucasSantana-Dev
LucasSantana-Dev merged commit b6eaa1a into main Apr 13, 2026
12 checks passed
LucasSantana-Dev added a commit that referenced this pull request May 13, 2026
add Brazilian noise patterns (Tradução, Legendado, Clipe Oficial, hashtags,
bare Lyrics) and extractSongCore() to identify the core song title from
artist-prefixed or inverted "Song - Artist" formats.

buildExcludedKeys and isDuplicateCandidate now also check a core-title key,
so "Beyoncé - Halo (Tradução/Legendado)", "Halo - Beyoncé (Lyrics)", and
"Beyoncé - Halo Lyrics #music" all correctly dedup against a history entry
of "Beyoncé - Halo".
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/autoplay-title-dedup branch May 23, 2026 02:21

This branch was successfully deployed

1 active deployment
Preview — 8f77fbd7 Deployed Apr 13, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant