mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-02-10 17:10:45 +01:00
Add sanitation of Stable Horde prompts
This commit is contained in:
parent
1c095415a4
commit
4f80085fa3
@ -156,6 +156,7 @@ const defaultSettings = {
|
|||||||
horde: false,
|
horde: false,
|
||||||
horde_nsfw: false,
|
horde_nsfw: false,
|
||||||
horde_karras: true,
|
horde_karras: true,
|
||||||
|
horde_sanitize: true,
|
||||||
|
|
||||||
// Refine mode
|
// Refine mode
|
||||||
refine_mode: false,
|
refine_mode: false,
|
||||||
@ -252,6 +253,7 @@ async function loadSettings() {
|
|||||||
$('#sd_horde').prop('checked', extension_settings.sd.horde);
|
$('#sd_horde').prop('checked', extension_settings.sd.horde);
|
||||||
$('#sd_horde_nsfw').prop('checked', extension_settings.sd.horde_nsfw);
|
$('#sd_horde_nsfw').prop('checked', extension_settings.sd.horde_nsfw);
|
||||||
$('#sd_horde_karras').prop('checked', extension_settings.sd.horde_karras);
|
$('#sd_horde_karras').prop('checked', extension_settings.sd.horde_karras);
|
||||||
|
$('#sd_horde_sanitize').prop('checked', extension_settings.sd.horde_sanitize);
|
||||||
$('#sd_restore_faces').prop('checked', extension_settings.sd.restore_faces);
|
$('#sd_restore_faces').prop('checked', extension_settings.sd.restore_faces);
|
||||||
$('#sd_enable_hr').prop('checked', extension_settings.sd.enable_hr);
|
$('#sd_enable_hr').prop('checked', extension_settings.sd.enable_hr);
|
||||||
$('#sd_refine_mode').prop('checked', extension_settings.sd.refine_mode);
|
$('#sd_refine_mode').prop('checked', extension_settings.sd.refine_mode);
|
||||||
@ -439,16 +441,21 @@ function onNovelAnlasGuardInput() {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onHordeNsfwInput() {
|
function onHordeNsfwInput() {
|
||||||
extension_settings.sd.horde_nsfw = !!$(this).prop('checked');
|
extension_settings.sd.horde_nsfw = !!$(this).prop('checked');
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onHordeKarrasInput() {
|
function onHordeKarrasInput() {
|
||||||
extension_settings.sd.horde_karras = !!$(this).prop('checked');
|
extension_settings.sd.horde_karras = !!$(this).prop('checked');
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onHordeSanitizeInput() {
|
||||||
|
extension_settings.sd.horde_sanitize = !!$(this).prop('checked');
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
function onRestoreFacesInput() {
|
function onRestoreFacesInput() {
|
||||||
extension_settings.sd.restore_faces = !!$(this).prop('checked');
|
extension_settings.sd.restore_faces = !!$(this).prop('checked');
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
@ -1243,6 +1250,7 @@ async function generateHordeImage(prompt) {
|
|||||||
nsfw: extension_settings.sd.horde_nsfw,
|
nsfw: extension_settings.sd.horde_nsfw,
|
||||||
restore_faces: !!extension_settings.sd.restore_faces,
|
restore_faces: !!extension_settings.sd.restore_faces,
|
||||||
enable_hr: !!extension_settings.sd.enable_hr,
|
enable_hr: !!extension_settings.sd.enable_hr,
|
||||||
|
sanitize: !!extension_settings.sd.horde_sanitize,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1584,6 +1592,7 @@ jQuery(async () => {
|
|||||||
$('#sd_height').on('input', onHeightInput);
|
$('#sd_height').on('input', onHeightInput);
|
||||||
$('#sd_horde_nsfw').on('input', onHordeNsfwInput);
|
$('#sd_horde_nsfw').on('input', onHordeNsfwInput);
|
||||||
$('#sd_horde_karras').on('input', onHordeKarrasInput);
|
$('#sd_horde_karras').on('input', onHordeKarrasInput);
|
||||||
|
$('#sd_horde_sanitize').on('input', onHordeSanitizeInput);
|
||||||
$('#sd_restore_faces').on('input', onRestoreFacesInput);
|
$('#sd_restore_faces').on('input', onRestoreFacesInput);
|
||||||
$('#sd_enable_hr').on('input', onHighResFixInput);
|
$('#sd_enable_hr').on('input', onHighResFixInput);
|
||||||
$('#sd_refine_mode').on('input', onRefineModeInput);
|
$('#sd_refine_mode').on('input', onRefineModeInput);
|
||||||
|
@ -58,6 +58,12 @@
|
|||||||
Allow NSFW images from Horde
|
Allow NSFW images from Horde
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
<label for="sd_horde_sanitize" class="checkbox_label">
|
||||||
|
<input id="sd_horde_sanitize" type="checkbox" />
|
||||||
|
<span data-i18n="Sanitize prompts (recommended)">
|
||||||
|
Sanitize prompts (recommended)
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
<label for="sd_horde_karras" class="checkbox_label">
|
<label for="sd_horde_karras" class="checkbox_label">
|
||||||
<input id="sd_horde_karras" type="checkbox" />
|
<input id="sd_horde_karras" type="checkbox" />
|
||||||
<span data-i18n="Karras (not all samplers supported)">
|
<span data-i18n="Karras (not all samplers supported)">
|
||||||
|
46
src/horde.js
46
src/horde.js
@ -17,6 +17,41 @@ async function getHordeClient() {
|
|||||||
return ai_horde;
|
return ai_horde;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes dirty no-no words from the prompt.
|
||||||
|
* Taken verbatim from KAI Lite's implementation (AGPLv3).
|
||||||
|
* https://github.com/LostRuins/lite.koboldai.net/blob/main/index.html#L7786C2-L7811C1
|
||||||
|
* @param {string} prompt Prompt to sanitize
|
||||||
|
* @returns {string} Sanitized prompt
|
||||||
|
*/
|
||||||
|
function sanitizeHordeImagePrompt(prompt) {
|
||||||
|
if (!prompt) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//to avoid flagging from some image models, always swap these words
|
||||||
|
prompt = prompt.replace(/\b(girl)\b/gmi, "woman");
|
||||||
|
prompt = prompt.replace(/\b(boy)\b/gmi, "man");
|
||||||
|
prompt = prompt.replace(/\b(girls)\b/gmi, "women");
|
||||||
|
prompt = prompt.replace(/\b(boys)\b/gmi, "men");
|
||||||
|
|
||||||
|
//always remove these high risk words from prompt, as they add little value to image gen while increasing the risk the prompt gets flagged
|
||||||
|
prompt = prompt.replace(/\b(under.age|under.aged|underage|underaged|loli|pedo|pedophile|(\w+).year.old|(\w+).years.old|minor|prepubescent|minors|shota)\b/gmi, "");
|
||||||
|
|
||||||
|
//if nsfw is detected, do not remove it but apply additional precautions
|
||||||
|
let isNsfw = prompt.match(/\b(cock|ahegao|hentai|uncensored|lewd|cocks|deepthroat|deepthroating|dick|dicks|cumshot|lesbian|fuck|fucked|fucking|sperm|naked|nipples|tits|boobs|breasts|boob|breast|topless|ass|butt|fingering|masturbate|masturbating|bitch|blowjob|pussy|piss|asshole|dildo|dildos|vibrator|erection|foreskin|handjob|nude|penis|porn|vibrator|virgin|vagina|vulva|threesome|orgy|bdsm|hickey|condom|testicles|anal|bareback|bukkake|creampie|stripper|strap-on|missionary|clitoris|clit|clitty|cowgirl|fleshlight|sex|buttplug|milf|oral|sucking|bondage|orgasm|scissoring|railed|slut|sluts|slutty|cumming|cunt|faggot|sissy|anal|anus|cum|semen|scat|nsfw|xxx|explicit|erotic|horny|aroused|jizz|moan|rape|raped|raping|throbbing|humping)\b/gmi);
|
||||||
|
|
||||||
|
if (isNsfw) {
|
||||||
|
//replace risky subject nouns with person
|
||||||
|
prompt = prompt.replace(/\b(youngster|infant|baby|toddler|child|teen|kid|kiddie|kiddo|teenager|student|preteen|pre.teen)\b/gmi, "person");
|
||||||
|
|
||||||
|
//remove risky adjectives and related words
|
||||||
|
prompt = prompt.replace(/\b(young|younger|youthful|youth|small|smaller|smallest|girly|boyish|lil|tiny|teenaged|lit[tl]le|school.aged|school|highschool|kindergarten|teens|children|kids)\b/gmi, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {import("express").Express} app
|
* @param {import("express").Express} app
|
||||||
@ -108,6 +143,17 @@ function registerEndpoints(app, jsonParser) {
|
|||||||
request.body.prompt = String(request.body.prompt).substring(0, maxLength);
|
request.body.prompt = String(request.body.prompt).substring(0, maxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize prompt if requested
|
||||||
|
if (request.body.sanitize) {
|
||||||
|
const sanitized = sanitizeHordeImagePrompt(request.body.prompt);
|
||||||
|
|
||||||
|
if (request.body.prompt !== sanitized) {
|
||||||
|
console.log('Stable Horde prompt was sanitized.');
|
||||||
|
}
|
||||||
|
|
||||||
|
request.body.prompt = sanitized;
|
||||||
|
}
|
||||||
|
|
||||||
const api_key_horde = readSecret(SECRET_KEYS.HORDE) || ANONYMOUS_KEY;
|
const api_key_horde = readSecret(SECRET_KEYS.HORDE) || ANONYMOUS_KEY;
|
||||||
console.log('Stable Horde request:', request.body);
|
console.log('Stable Horde request:', request.body);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user