fix: Keep Composing appends continuation instead of replacing prompt
Two fixes: - Backend: MAESTRO_COMPLETE_PROMPT now instructs Gemini to output ONLY the continuation text, not a rewrite. No repeating user's words. - Frontend: complete mode appends result to existing prompt with smart separator logic (lowercase start = space, uppercase = period+space). generate mode still replaces the empty prompt as before.
This commit is contained in:
1 parent
da5e63817f
commit
050c104201
2 files changed
+34
-14
No files matched your search
@@ -127,19 +127,18 @@ Output ONLY the prompt text. No numbers, no labels, no commentary."""
|
|||||||
|
|
||||||
MAESTRO_COMPLETE_PROMPT = """You are Maestro, an expert music prompt writer for AI music generation models (specifically Google Lyria).
|
MAESTRO_COMPLETE_PROMPT = """You are Maestro, an expert music prompt writer for AI music generation models (specifically Google Lyria).
|
||||||
|
|
||||||
The user has started writing a prompt and wants you to turn it into a complete, polished prompt. Here is what they have so far:
|
The user has written the beginning of a prompt and wants you to continue it. Here is what they have:
|
||||||
|
|
||||||
"{user_input}"
|
"{user_input}"
|
||||||
|
|
||||||
Rewrite and expand their idea into a single detailed, evocative music generation prompt. Your result should:
|
Continue and expand their idea. Add 2-3 sentences of specific musical detail — genre, instrumentation, mood, tempo, structure, production style. Your continuation will be appended directly after their text, so:
|
||||||
- Incorporate the user's existing words naturally — they should recognize their idea in the result
|
|
||||||
- Expand with specific details about genre, instrumentation, mood, tempo, structure, or production style
|
|
||||||
- Read as one complete, cohesive paragraph ready to use as-is
|
|
||||||
- Be between 2-4 sentences total
|
|
||||||
|
|
||||||
The output replaces what they wrote, so it must be a self-contained, finished prompt.
|
- Do NOT repeat or rephrase what they wrote
|
||||||
|
- Do NOT add a period if their text ends mid-sentence
|
||||||
|
- Start naturally as if picking up from where they left off
|
||||||
|
- Be vivid and specific — a producer should be able to generate from this
|
||||||
|
|
||||||
Output ONLY the completed prompt text. No numbers, no labels, no commentary."""
|
Output ONLY your continuation text. No labels, no commentary, no quotes."""
|
||||||
|
|
||||||
|
|
||||||
MAESTRO_STRUCTURED_PROMPT = """You are Maestro, an expert music prompt writer for AI music generation models (specifically Google Lyria).
|
MAESTRO_STRUCTURED_PROMPT = """You are Maestro, an expert music prompt writer for AI music generation models (specifically Google Lyria).
|
||||||
|
|||||||
@@ -188,10 +188,21 @@ export default function Generator({ onGenerate }: Props) {
|
|||||||
<MaestroButton
|
<MaestroButton
|
||||||
prompt={prompt}
|
prompt={prompt}
|
||||||
onResult={(result, mode) => {
|
onResult={(result, mode) => {
|
||||||
setPrompt(result)
|
if (mode === 'complete') {
|
||||||
if (mode === 'generate') {
|
// Append continuation to existing prompt
|
||||||
setError('')
|
setPrompt(prev => {
|
||||||
|
const trimmed = prev.trimEnd()
|
||||||
|
// If result starts lowercase, it flows from the input — just space
|
||||||
|
// If result starts uppercase, treat as new sentence — period + space
|
||||||
|
const startsLower = /^[a-z]/.test(result)
|
||||||
|
const separator = startsLower ? ' ' : '. '
|
||||||
|
return trimmed + separator + result
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Generate mode: replace empty prompt
|
||||||
|
setPrompt(result)
|
||||||
}
|
}
|
||||||
|
setError('')
|
||||||
}}
|
}}
|
||||||
onError={(msg) => setError(msg)}
|
onError={(msg) => setError(msg)}
|
||||||
/>
|
/>
|
||||||
@@ -214,9 +225,19 @@ export default function Generator({ onGenerate }: Props) {
|
|||||||
prompt={Object.values(structuredPrompt).filter(Boolean).join(' ')}
|
prompt={Object.values(structuredPrompt).filter(Boolean).join(' ')}
|
||||||
structured={isPro}
|
structured={isPro}
|
||||||
onResult={(result, mode) => {
|
onResult={(result, mode) => {
|
||||||
// Fallback: plain text mode for non-Pro, put result in 'additional'
|
if (mode === 'complete') {
|
||||||
setStructuredPrompt(prev => ({ ...prev, additional: result }))
|
// Fallback: append to additional field
|
||||||
if (mode === 'generate') setError('')
|
setStructuredPrompt(prev => {
|
||||||
|
const existing = prev.additional?.trim() || ''
|
||||||
|
const startsLower = /^[a-z]/.test(result)
|
||||||
|
const separator = startsLower ? ' ' : '. '
|
||||||
|
return { ...prev, additional: existing + separator + result }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Generate: put in additional
|
||||||
|
setStructuredPrompt(prev => ({ ...prev, additional: result }))
|
||||||
|
}
|
||||||
|
setError('')
|
||||||
}}
|
}}
|
||||||
onStructuredResult={(fields, mode) => {
|
onStructuredResult={(fields, mode) => {
|
||||||
// Structured mode: merge fields into structuredPrompt, preserving user edits
|
// Structured mode: merge fields into structuredPrompt, preserving user edits
|
||||||
|
|||||||
Reference in new issue
Block a user