Skip to content

agent: @U0AJM7X8FBR # Song Filtering for Content Creation PipelineProblemThe co#111

Open
sweetmantech wants to merge 1 commit intomainfrom
feature/song-filtering-for-content-pipeline
Open

agent: @U0AJM7X8FBR # Song Filtering for Content Creation PipelineProblemThe co#111
sweetmantech wants to merge 1 commit intomainfrom
feature/song-filtering-for-content-pipeline

Conversation

@sweetmantech
Copy link
Copy Markdown
Contributor

@sweetmantech sweetmantech commented Mar 26, 2026

Automated PR from coding agent.

Summary by CodeRabbit

  • New Features

    • Content creation now accepts an optional songs parameter to filter which songs are available for selection during the process
  • Tests

    • Added test coverage for song filtering behavior when songs are specified or omitted
    • Added tests for error handling when specified songs cannot be found
    • Added validation tests for the updated content creation schema

Adds an optional `songs` array to the content creation payload. When
provided, only songs matching the given slugs are eligible for selection.
When omitted, existing behavior (all songs) is preserved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

This pull request adds optional song filtering to the content creation pipeline. A new songs?: string[] parameter is introduced to the schema, task handler, and audio selection function, allowing callers to restrict eligible songs by slug. Corresponding tests validate the filtering behavior across various scenarios.

Changes

Cohort / File(s) Summary
Schema Definition & Tests
src/schemas/contentCreationSchema.ts, src/schemas/__tests__/contentCreationSchema.test.ts
Added optional songs?: string[] field to the payload schema; added tests verifying the schema accepts and validates provided song arrays, and correctly omits the field when not provided.
Audio Selection Logic & Tests
src/content/selectAudioClip.ts, src/content/__tests__/selectAudioClip.test.ts
Extended selectAudioClip function signature with optional songs parameter; implemented filtering to match only song paths containing /songs/{slug}/ for provided slugs; added comprehensive test suite covering scenarios with no songs, provided songs, unmatched songs, and multiple valid songs.
Task Integration
src/tasks/createContentTask.ts
Updated selectAudioClip call to pass payload.songs as an argument, threading the optional filter through the content creation pipeline.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related PRs

Poem

🐰 A filter's found, sweet songs to choose,
By slug and path, we pick what we use,
Schema to task, the flow runs clear,
Tests validate each path we steer! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title is malformed and unclear—it contains a user mention, hashtag, and incomplete text ('ProblemThe co'), making it difficult to understand the primary change at a glance. Revise the title to be concise and descriptive of the main change, e.g., 'Add optional song filtering to content creation pipeline' or 'Support song slug filtering in selectAudioClip'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 feature/song-filtering-for-content-pipeline

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 `@src/content/__tests__/selectAudioClip.test.ts`:
- Around line 58-119: Add a test to the "song filtering" suite verifying that
passing songs: [] to selectAudioClip is treated the same as omitting the songs
field (i.e., no filter): mock listArtistSongs to return allSongPaths, call
selectAudioClip with songs: [], then assert behavior consistent with the first
test (e.g., vi.mocked(listArtistSongs) was called and selectAudioClip resolves
and/or fetchGithubFile is called for any eligible song); use the existing test
helpers and the same structure as the other tests so this edge case is covered.

In `@src/content/selectAudioClip.ts`:
- Around line 67-74: The code currently only applies the songs filter when
songs.length > 0, which causes an explicit empty songs array to be ignored;
change the condition to detect the presence of the songs parameter (e.g., if
(songs !== undefined && songs !== null) or if (Array.isArray(songs))) so that
songPaths is always filtered against the provided songs array (even when empty),
and keep the existing throw when songPaths.length === 0; update the block around
the songPaths filtering in selectAudioClip (variables: songs, songPaths)
accordingly.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 641587a6-7974-4f0a-b7ec-72f6b37058e6

📥 Commits

Reviewing files that changed from the base of the PR and between bcbda15 and f6bd781.

📒 Files selected for processing (5)
  • src/content/__tests__/selectAudioClip.test.ts
  • src/content/selectAudioClip.ts
  • src/schemas/__tests__/contentCreationSchema.test.ts
  • src/schemas/contentCreationSchema.ts
  • src/tasks/createContentTask.ts

Comment on lines +58 to +119
describe("song filtering", () => {
it("picks from all songs when songs is omitted", async () => {
vi.mocked(listArtistSongs).mockResolvedValue(allSongPaths);

await selectAudioClip({
githubRepo: "https://github.com/org/repo",
artistSlug: "test-artist",
clipDuration: 15,
lipsync: false,
});

// listArtistSongs was called — all 3 are eligible
expect(vi.mocked(listArtistSongs)).toHaveBeenCalledOnce();
});

it("filters to specified songs when songs array is provided", async () => {
vi.mocked(listArtistSongs).mockResolvedValue(allSongPaths);

await selectAudioClip({
githubRepo: "https://github.com/org/repo",
artistSlug: "test-artist",
clipDuration: 15,
lipsync: false,
songs: ["adhd"],
});

// Only adhd.mp3 is eligible — transcribeSong should be called with adhd path
expect(vi.mocked(fetchGithubFile)).toHaveBeenCalledWith(
expect.any(String),
"artists/test-artist/songs/adhd/adhd.mp3",
);
});

it("throws when none of the specified songs are found", async () => {
vi.mocked(listArtistSongs).mockResolvedValue(allSongPaths);

await expect(
selectAudioClip({
githubRepo: "https://github.com/org/repo",
artistSlug: "test-artist",
clipDuration: 15,
lipsync: false,
songs: ["nonexistent-song"],
}),
).rejects.toThrow("None of the specified songs [nonexistent-song] were found");
});

it("filters to multiple specified songs", async () => {
vi.mocked(listArtistSongs).mockResolvedValue(allSongPaths);

// Should not throw — both adhd and hiccups exist
await expect(
selectAudioClip({
githubRepo: "https://github.com/org/repo",
artistSlug: "test-artist",
clipDuration: 15,
lipsync: false,
songs: ["adhd", "hiccups"],
}),
).resolves.toBeDefined();
});
});
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 | 🟡 Minor

Add a regression test for songs: [] semantics.

Given Line 67 in src/content/selectAudioClip.ts, an explicit empty array currently behaves like “no filter.” Please add a test that locks the intended behavior for songs: [] so this edge case doesn’t regress.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/__tests__/selectAudioClip.test.ts` around lines 58 - 119, Add a
test to the "song filtering" suite verifying that passing songs: [] to
selectAudioClip is treated the same as omitting the songs field (i.e., no
filter): mock listArtistSongs to return allSongPaths, call selectAudioClip with
songs: [], then assert behavior consistent with the first test (e.g.,
vi.mocked(listArtistSongs) was called and selectAudioClip resolves and/or
fetchGithubFile is called for any eligible song); use the existing test helpers
and the same structure as the other tests so this edge case is covered.

Comment on lines +67 to +74
if (songs && songs.length > 0) {
songPaths = songPaths.filter(path =>
songs.some(slug => path.includes(`/songs/${slug}/`)),
);
if (songPaths.length === 0) {
throw new Error(`None of the specified songs [${songs.join(", ")}] were found`);
}
}
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

Honor explicit empty songs input instead of falling back to all songs.

Line 67 currently skips filtering when songs is [], so an explicit filter can unintentionally select any song. That breaks the payload contract where provided songs should constrain eligibility.

💡 Suggested fix
-  if (songs && songs.length > 0) {
-    songPaths = songPaths.filter(path =>
-      songs.some(slug => path.includes(`/songs/${slug}/`)),
-    );
+  if (songs !== undefined) {
+    const requestedSlugs = songs.map(slug => slug.trim()).filter(Boolean);
+    if (requestedSlugs.length === 0) {
+      throw new Error("songs must include at least one non-empty slug when provided");
+    }
+
+    songPaths = songPaths.filter(path =>
+      requestedSlugs.some(slug => path.includes(`/songs/${slug}/`)),
+    );
     if (songPaths.length === 0) {
-      throw new Error(`None of the specified songs [${songs.join(", ")}] were found`);
+      throw new Error(`None of the specified songs [${requestedSlugs.join(", ")}] were found`);
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/content/selectAudioClip.ts` around lines 67 - 74, The code currently only
applies the songs filter when songs.length > 0, which causes an explicit empty
songs array to be ignored; change the condition to detect the presence of the
songs parameter (e.g., if (songs !== undefined && songs !== null) or if
(Array.isArray(songs))) so that songPaths is always filtered against the
provided songs array (even when empty), and keep the existing throw when
songPaths.length === 0; update the block around the songPaths filtering in
selectAudioClip (variables: songs, songPaths) accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant