Compose Writing Prompt
Compose Writing Prompt Turns Your Brief Into Instructions a Small LLM Can Actually Follow
- brief
- engine
- prompt
- request
What it is
This is the node that writes the prompt for your writer. You give it a brief and the loaded music model's rules; it hands back one plain string you can plug into any text-generation node - ComfyUI's native Generate Text, an Ollama node, whatever you already run - plus a request object that records exactly what was asked.
Why not just type an instruction into the LLM node? Because YuE2 and MiniMax Music 3 want different things, and the difference matters. YuE2 wants a one-line style under 40 words, [Tag] sections from a fixed vocabulary, and lyrics that land on a score's sections. MiniMax wants a structured 5,000-token caption with global metadata, vocal details and arrangement. Composing that by hand per song is exactly the kind of chore you'd get wrong at 2am. This node reads the engine descriptor, so the instructions follow the model that's actually loaded rather than a README you read once.
How it works
Wire brief from Song Brief or Cover Brief, and engine from Engine Profile (the node inside Plenio's model block that sniffs which music model sits behind a CLIP object). The node then assembles the prompt from the brief's fields plus the engine's writing rules.
Two inputs do real work only sometimes, and the node is smart about it - they're lazy, meaning ComfyUI only asks upstream for them when the brief actually needs them. language is pulled from Transcribe Lyrics only when you're making an original-lyrics cover and the brief's language is set to auto. reference_lyrics is pulled only for new-lyrics covers with the phrasing reference turned on, and because those lyrics come sectioned, the writer gets a syllable target per line. Skip them and the ASR never runs - which is the point, since lyrics transcription is the one part of this pack that wants an extra pip install.
score is optional but worth wiring. If the final score is connected, its section names become the lyrics' section tags, and on covers the score's phrasing, tempo and vocal range constrain what the writer produces, so the words fit the melody instead of the other way round. detail (concise / standard / rich) is the only knob for lyric density and it's tucked into the advanced drawer for a reason - most people leave it on standard.
The two outputs are the pair that matters: prompt goes to the text-generation node, and request goes to Parse Song Draft, which uses it to check the answer against the question. Break that pair and the checks become noise.
Install
# ComfyUI Manager → search "Plenio Music Production System" → Install → restart
# or:
cd ComfyUI/custom_nodes
git clone https://github.com/jplenio/Plenio-Music-Production-System
The pack itself installs no Python packages. You still need a writer model on disk - Plenio's templates use the Gemma 4 E4B text encoder file as the writer, downloaded through ComfyUI's missing-model dialog when you open a template. ComfyUI 0.37.0+ required.
Common issues
- The prompt looks like a wall of text. It is one; that's the format, and it's why
requestexists. Don't hand-edit the string expecting coherence downstream - edit the brief. - The writer ignores the style length. YuE2's rules cap the style at 40 words with a warning band to 60 and a hard limit of 120; a model that overshoots gets reported by Parse Song Draft, and the Song Sheet will flag the overflow.
- Cover lyrics don't line up with the melody. Check that
scoreis connected. Without the score, the writer has no phrasing or tempo to write against, and you get lyrics that are the right mood and the wrong shape. - An ASR run you didn't want. If
reference_lyricsis fed by a Transcribe Lyrics node that also feeds something else, that branch still executes on its own terms. The laziness only skips it when nothing needs it.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| brief | PLENIO_BRIEF | From Song Brief or Cover Brief. | |
| engine | PLENIO_ENGINE | From the music model block (Engine Profile). | |
| detail | COMBO | standard | How compact or rich the lyrics should be. |
| scoreopt | STRING | The final score: its sections (and for covers its phrasing and tempo) guide the lyrics. | |
| languageopt | STRING | Detected lyrics language (Transcribe Lyrics); requested only for original-lyrics covers whose brief says 'auto'. | |
| reference_lyricsopt | STRING | The source's lyrics draft (Transcribe Lyrics: lyrics); requested only for new-lyrics covers with the phrasing reference. Sectioned lyrics give the writer a syllable target per line. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | Prompt text for the writing model. |
| request | PLENIO_REQUEST | What was asked; Parse Song Draft checks the answer against it. |