Skip to content

RFC: AI-assisted playlist generation via Nextcloud Assistant / TaskProcessing #142

Description

@sturlan

Summary

Idea: let users generate a playlist from a free-text description ("upbeat 90s rock", "chill stuff I haven't played in a while") using Nextcloud's Assistant/TaskProcessing infrastructure, rather than manually building Advanced Search criteria by hand.

Posting this as an RFC before writing any code — want feedback on the approach and whether it's a direction worth pursuing, especially given the maincontroller.js refactor already planned.

Why this seems tractable

The hard part of "AI playlist generation" is usually that you can't fit a whole library into an LLM's context window, so you'd normally need embeddings/vector search infrastructure that doesn't exist here. But Music already has a full structured filter engine in Advanced Search (AdvSearchRules.php, BaseMapper::findAllAdvanced) — {rule, operator, input} criteria (genre, artist, year, BPM, favorite, play count, date added, etc.) resolved server-side via SQL across the whole library. That's exactly the shape an LLM is good at producing from natural language, and it sidesteps the context-window problem entirely — the LLM only has to fill in a known schema, not reason about 70k+ tracks.

Proposed approach

  1. New UI affordance in Music: a free-text "Describe a playlist" input.
  2. New backend endpoint that:
    • builds a prompt from the existing Advanced Search rule catalogue (rule keys, types, valid operators) + the user's text
    • schedules a core:text2text task via OCP\TaskProcessing\IManager, asking for a JSON response shaped like {conjunction, rules: [{rule, operator, input}, ...]}
    • validates the returned JSON strictly against the known rule/operator list (LLM output isn't guaranteed to be valid JSON or to stay within the schema, so this needs to be defensive — reject/drop anything unrecognized)
    • feeds the validated criteria into the existing findAllAdvanced() path and builds the playlist via PlaylistBusinessLayer, reusing tested filtering logic rather than adding a new query engine
  3. Feature depends on the instance having an LLM provider configured for TaskProcessing (OpenAI/local model/etc. via whatever integration app is installed) — Music would check hasProviders() / getAvailableTaskTypeIds() and hide the feature entirely when unavailable, rather than degrading awkwardly.

Open questions

  • Where should this live in the UI — sidebar action, a variant of the existing smart-list panel, something else?
  • core:text2text has no structured-output guarantee. Is prompt-engineering + strict server-side validation good enough, or is this worth a dedicated TaskType instead (tradeoff: a custom type needs a provider that implements it — core providers won't, so in practice this would leave the feature unusable except for providers that specifically add support)?
  • Any concern about scope/overlap with the maincontroller.js Promise refactor, given the new endpoint's frontend piece would touch similar view-controller wiring?

Not attempting this yet — wanted to get a read on the idea and the approach before spending time on an implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions