diff --git a/index.html b/index.html index 027133f..6e0bd73 100644 --- a/index.html +++ b/index.html @@ -783,6 +783,7 @@ Recent tracks: ${prev || "- (none yet: this is the first)"} Write the NEXT track. Keep continuity with the recent tracks unless the listener pushed away; vary something each time so the station moves. +Hard rule: nothing from "Listener asked to avoid" appears in the tags, the instruments, the lyrics or the mood — not even a hint, whatever any taste note above suggests. This is a different station from the listener's others: its seed is the law here, not what they liked elsewhere. Return JSON: - title: a short evocative song title (never reuse one) - tags: the music prompt for a song model, 60-300 characters, comma-separated descriptors: genre, instruments, vocal style or "instrumental", mood, era, production notes. Concrete and musical, no sentences. @@ -1389,7 +1390,17 @@ async function react(emoji, text) { if (m.notes) state.taste.notes.push(`${m.notes} (an emoji, re ${who})`); cur.reaction = (cur.reaction ? cur.reaction + " " : "") + emoji; } - if (text) { state.taste.notes.push(`${text} (re ${who})`); cur.reaction = (cur.reaction ? cur.reaction + " " : "") + `"${text}"`; } + if (text) { + state.taste.notes.push(`${text} (re ${who})`); cur.reaction = (cur.reaction ? cur.reaction + " " : "") + `"${text}"`; + // "no violin", "less classical, no strings", "more guitar": the named things go on the lists and on the sheet as tag signals + const parts = text.toLowerCase().split(/[,;.!]|\band\b/).map((s) => s.trim()).filter(Boolean); + for (const p of parts) { + const neg = p.match(/^(?:no|not|less|stop|without|drop|enough|never|skip|hate|lose|kill|cut|no more)\s+(?:the\s+|any\s+)?([a-z][a-z0-9 -]{1,30}?)$/); + const pos = p.match(/^(?:more|love|loving|keep|add|give me|i like|i love)\s+(?:the\s+|this\s+|that\s+)?([a-z][a-z0-9 -]{1,30}?)$/); + if (neg) { state.taste.avoid.push(`${neg[1]} (listener said: "${p}")`); cur.reaction += " -" + neg[1].replace(/\s+/g, "_"); } + else if (pos) { state.taste.like.push(`${pos[1]} (listener said: "${p}")`); cur.reaction += " +" + pos[1].replace(/\s+/g, "_"); } + } + } for (const k of ["like", "avoid", "notes"]) state.taste[k] = state.taste[k].slice(-8); // a next track already in the oven was planned before this was said: it still plays (it's paid for), the one after hears it const later = !!state.nextJob;