Files
TowstyandCursor a51118d92a Pass through PE refusals to the raw prompt and pin adult PE system prompts.
Enhance no longer fails the studio job when the rewrite refuses or comes back empty; host prompt copies keep the official steps plus the adult appendix after a node re-clone.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-26 14:46:24 -05:00

44 lines
2.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** Qwen PE refusal / empty-rewrite detection — fail open to promptRaw. */
const REFUSAL_RE =
/i cannot|i can't|i['’]m not able|i am not able|cannot assist|can't assist|won['’]t create|will not create|against my|not appropriate|\bsafety\b|content policy|抱歉|无法|不能协助|不符合/i
const STOP = new Set([
'the', 'and', 'for', 'are', 'was', 'were', 'been', 'being', 'this', 'that', 'with', 'from',
'into', 'your', 'have', 'will', 'would', 'could', 'should', 'about', 'there', 'their', 'them',
'then', 'than', 'when', 'what', 'which', 'while', 'where', 'make', 'made', 'like', 'just',
'only', 'also', 'over', 'under', 'after', 'before', 'between', 'through', 'image', 'photo',
'picture', 'please', 'create', 'generate', 'show', 'want', 'need', 'scene', 'style', 'prompt',
'edit', 'change', 'keep', 'using', 'into', 'onto', 'her', 'him', 'his', 'she', 'they', 'them',
])
/** Concrete tokens from the user brief (latin words ≥3 or CJK runs). */
export function concreteTokens(text) {
const raw = String(text || '').toLowerCase().match(/[a-z][a-z0-9-]{2,}|[\u4e00-\u9fff]{2,}/g) || []
return [...new Set(raw)].filter(w => !STOP.has(w))
}
function isGutted(userPrompt, rewritten) {
const user = String(userPrompt || '').trim()
const out = String(rewritten || '').trim()
if (!user || !out) return !out
if (out.length >= user.length) return false
const nouns = concreteTokens(user)
if (!nouns.length) return false
const lower = out.toLowerCase()
return !nouns.some(n => lower.includes(n))
}
/**
* @returns {{ refused: boolean, reason: string }}
*/
export function qwen21PeRefusal(userPrompt, { positive_prompt, thinking, parse_ok } = {}) {
const positive = String(positive_prompt || '').trim()
const think = String(thinking || '').trim()
if (!parse_ok && !positive) return { refused: true, reason: 'empty rewrite (parse_ok false)' }
if (!positive) return { refused: true, reason: 'empty rewrite' }
if (REFUSAL_RE.test(positive) || REFUSAL_RE.test(think)) return { refused: true, reason: 'model refused' }
if (isGutted(userPrompt, positive)) return { refused: true, reason: 'gutted rewrite' }
return { refused: false, reason: '' }
}