From 75ebdf394a14955e9d3b5349171c3389373b393c Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Thu, 4 Apr 2024 20:40:47 +0300
Subject: [PATCH 01/16] Add pollinations as image generation source
---
.../extensions/stable-diffusion/index.js | 111 +++++++++++++++++-
.../extensions/stable-diffusion/settings.html | 27 ++++-
src/endpoints/stable-diffusion.js | 40 ++++++-
3 files changed, 171 insertions(+), 7 deletions(-)
diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js
index f4e47ca84..eb58fae9f 100644
--- a/public/scripts/extensions/stable-diffusion/index.js
+++ b/public/scripts/extensions/stable-diffusion/index.js
@@ -48,6 +48,7 @@ const sources = {
comfy: 'comfy',
togetherai: 'togetherai',
drawthings: 'drawthings',
+ pollinations: 'pollinations',
};
const generationMode = {
@@ -254,6 +255,10 @@ const defaultSettings = {
// ComyUI settings
comfy_url: 'http://127.0.0.1:8188',
comfy_workflow: 'Default_Comfy_Workflow.json',
+
+ // Pollinations settings
+ pollinations_enhance: false,
+ pollinations_refine: false,
};
function processTriggers(chat, _, abort) {
@@ -383,6 +388,8 @@ async function loadSettings() {
$('#sd_novel_sm').prop('checked', extension_settings.sd.novel_sm);
$('#sd_novel_sm_dyn').prop('checked', extension_settings.sd.novel_sm_dyn);
$('#sd_novel_sm_dyn').prop('disabled', !extension_settings.sd.novel_sm);
+ $('#sd_pollinations_enhance').prop('checked', extension_settings.sd.pollinations_enhance);
+ $('#sd_pollinations_refine').prop('checked', extension_settings.sd.pollinations_refine);
$('#sd_horde').prop('checked', extension_settings.sd.horde);
$('#sd_horde_nsfw').prop('checked', extension_settings.sd.horde_nsfw);
$('#sd_horde_karras').prop('checked', extension_settings.sd.horde_karras);
@@ -828,6 +835,16 @@ function onNovelSmDynInput() {
saveSettingsDebounced();
}
+function onPollinationsEnhanceInput() {
+ extension_settings.sd.pollinations_enhance = !!$('#sd_pollinations_enhance').prop('checked');
+ saveSettingsDebounced();
+}
+
+function onPollinationsRefineInput() {
+ extension_settings.sd.pollinations_refine = !!$('#sd_pollinations_refine').prop('checked');
+ saveSettingsDebounced();
+}
+
function onHordeNsfwInput() {
extension_settings.sd.horde_nsfw = !!$(this).prop('checked');
saveSettingsDebounced();
@@ -1023,7 +1040,7 @@ async function onModelChange() {
extension_settings.sd.model = $('#sd_model').find(':selected').val();
saveSettingsDebounced();
- const cloudSources = [sources.horde, sources.novel, sources.openai, sources.togetherai];
+ const cloudSources = [sources.horde, sources.novel, sources.openai, sources.togetherai, sources.pollinations];
if (cloudSources.includes(extension_settings.sd.source)) {
return;
@@ -1188,6 +1205,9 @@ async function loadSamplers() {
case sources.togetherai:
samplers = ['N/A'];
break;
+ case sources.pollinations:
+ samplers = ['N/A'];
+ break;
}
for (const sampler of samplers) {
@@ -1368,6 +1388,9 @@ async function loadModels() {
case sources.togetherai:
models = await loadTogetherAIModels();
break;
+ case sources.pollinations:
+ models = await loadPollinationsModels();
+ break;
}
for (const model of models) {
@@ -1384,6 +1407,55 @@ async function loadModels() {
}
}
+async function loadPollinationsModels() {
+ return [
+ {
+ value: 'pixart',
+ text: 'PixArt-αlpha',
+ },
+ {
+ value: 'playground',
+ text: 'Playground v2',
+ },
+ {
+ value: 'dalle3xl',
+ text: 'DALL•E 3 XL',
+ },
+ {
+ value: 'formulaxl',
+ text: 'FormulaXL',
+ },
+ {
+ value: 'dreamshaper',
+ text: 'DreamShaper',
+ },
+ {
+ value: 'deliberate',
+ text: 'Deliberate',
+ },
+ {
+ value: 'dpo',
+ text: 'SDXL-DPO',
+ },
+ {
+ value: 'swizz8',
+ text: 'Swizz8',
+ },
+ {
+ value: 'juggernaut',
+ text: 'Juggernaut',
+ },
+ {
+ value: 'turbo',
+ text: 'SDXL Turbo',
+ },
+ {
+ value: 'realvis',
+ text: 'Realistic Vision',
+ },
+ ];
+}
+
async function loadTogetherAIModels() {
if (!secret_state[SECRET_KEYS.TOGETHERAI]) {
console.debug('TogetherAI API key is not set.');
@@ -1641,6 +1713,9 @@ async function loadSchedulers() {
case sources.togetherai:
schedulers = ['N/A'];
break;
+ case sources.pollinations:
+ schedulers = ['N/A'];
+ break;
case sources.comfy:
schedulers = await loadComfySchedulers();
break;
@@ -1706,6 +1781,9 @@ async function loadVaes() {
case sources.togetherai:
vaes = ['N/A'];
break;
+ case sources.pollinations:
+ vaes = ['N/A'];
+ break;
case sources.comfy:
vaes = await loadComfyVaes();
break;
@@ -2135,6 +2213,9 @@ async function sendGenerationRequest(generationType, prompt, characterName = nul
case sources.togetherai:
result = await generateTogetherAIImage(prefixedPrompt, negativePrompt);
break;
+ case sources.pollinations:
+ result = await generatePollinationsImage(prefixedPrompt, negativePrompt);
+ break;
}
if (!result.data) {
@@ -2181,6 +2262,30 @@ async function generateTogetherAIImage(prompt, negativePrompt) {
}
}
+async function generatePollinationsImage(prompt, negativePrompt) {
+ const result = await fetch('/api/sd/pollinations/generate', {
+ method: 'POST',
+ headers: getRequestHeaders(),
+ body: JSON.stringify({
+ prompt: prompt,
+ negative_prompt: negativePrompt,
+ model: extension_settings.sd.model,
+ width: extension_settings.sd.width,
+ height: extension_settings.sd.height,
+ enhance: extension_settings.sd.pollinations_enhance,
+ refine: extension_settings.sd.pollinations_refine,
+ }),
+ });
+
+ if (result.ok) {
+ const data = await result.json();
+ return { format: 'jpg', data: data?.image };
+ } else {
+ const text = await result.text();
+ throw new Error(text);
+ }
+}
+
/**
* Generates an "extras" image using a provided prompt and other settings.
*
@@ -2775,6 +2880,8 @@ function isValidState() {
return true;
case sources.togetherai:
return secret_state[SECRET_KEYS.TOGETHERAI];
+ case sources.pollinations:
+ return true;
}
}
@@ -2922,6 +3029,8 @@ jQuery(async () => {
$('#sd_novel_view_anlas').on('click', onViewAnlasClick);
$('#sd_novel_sm').on('input', onNovelSmInput);
$('#sd_novel_sm_dyn').on('input', onNovelSmDynInput);
+ $('#sd_pollinations_enhance').on('input', onPollinationsEnhanceInput);
+ $('#sd_pollinations_refine').on('input', onPollinationsRefineInput);
$('#sd_comfy_validate').on('click', validateComfyUrl);
$('#sd_comfy_url').on('input', onComfyUrlInput);
$('#sd_comfy_workflow').on('change', onComfyWorkflowChange);
diff --git a/public/scripts/extensions/stable-diffusion/settings.html b/public/scripts/extensions/stable-diffusion/settings.html
index cc2307e79..2e5687c4a 100644
--- a/public/scripts/extensions/stable-diffusion/settings.html
+++ b/public/scripts/extensions/stable-diffusion/settings.html
@@ -32,14 +32,15 @@
@@ -158,6 +159,22 @@
+
diff --git a/src/endpoints/stable-diffusion.js b/src/endpoints/stable-diffusion.js
index e2168cd80..104801538 100644
--- a/src/endpoints/stable-diffusion.js
+++ b/src/endpoints/stable-diffusion.js
@@ -684,7 +684,7 @@ drawthings.post('/generate', jsonParser, async (request, response) => {
const url = new URL(request.body.url);
url.pathname = '/sdapi/v1/txt2img';
- const body = {...request.body};
+ const body = { ...request.body };
delete body.url;
const result = await fetch(url, {
@@ -710,8 +710,46 @@ drawthings.post('/generate', jsonParser, async (request, response) => {
}
});
+const pollinations = express.Router();
+
+pollinations.post('/generate', jsonParser, async (request, response) => {
+ try {
+ const promptUrl = new URL(`https://image.pollinations.ai/prompt/${encodeURIComponent(request.body.prompt)}`);
+ const params = new URLSearchParams({
+ model: String(request.body.model),
+ negative_prompt: String(request.body.negative_prompt),
+ seed: String(Math.floor(Math.random() * 10_000_000)),
+ enhance: String(request.body.enhance ?? false),
+ refine: String(request.body.refine ?? false),
+ width: String(request.body.width ?? 1024),
+ height: String(request.body.height ?? 1024),
+ nologo: String(true),
+ nofeed: String(true),
+ });
+ promptUrl.search = params.toString();
+
+ console.log('Pollinations request URL:', promptUrl.toString());
+
+ const result = await fetch(promptUrl);
+
+ if (!result.ok) {
+ console.log('Pollinations returned an error.', result.status, result.statusText);
+ throw new Error('Pollinations request failed.');
+ }
+
+ const buffer = await result.buffer();
+ const base64 = buffer.toString('base64');
+
+ return response.send({ image: base64 });
+ } catch (error) {
+ console.log(error);
+ return response.sendStatus(500);
+ }
+});
+
router.use('/comfy', comfy);
router.use('/together', together);
router.use('/drawthings', drawthings);
+router.use('/pollinations', pollinations);
module.exports = { router };
From 99a7925be44af3765bcef920abfd7c875054442c Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Wed, 10 Apr 2024 00:04:20 +0300
Subject: [PATCH 02/16] Don't force a newline for story string if instruct wrap
is disabled
---
public/scripts/power-user.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js
index 7f7ea524a..0d7f8ca0e 100644
--- a/public/scripts/power-user.js
+++ b/public/scripts/power-user.js
@@ -1942,7 +1942,9 @@ export function renderStoryString(params) {
// add a newline to the end of the story string if it doesn't have one
if (output.length > 0 && !output.endsWith('\n')) {
- output += '\n';
+ if (!power_user.instruct.enabled || power_user.instruct.wrap) {
+ output += '\n';
+ }
}
return output;
From 69d219cd7e96b749e54e2c2c54f31013d4619e9f Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Wed, 10 Apr 2024 00:32:53 +0300
Subject: [PATCH 03/16] Allow trimming chat start with {{trim}} macro
---
public/script.js | 2 +-
public/scripts/templates/macros.html | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/public/script.js b/public/script.js
index b329c2c56..84a0e9d5d 100644
--- a/public/script.js
+++ b/public/script.js
@@ -4575,7 +4575,7 @@ function addChatsPreamble(mesSendString) {
function addChatsSeparator(mesSendString) {
if (power_user.context.chat_start) {
- return substituteParams(power_user.context.chat_start) + '\n' + mesSendString;
+ return substituteParams(power_user.context.chat_start + '\n') + mesSendString;
}
else {
diff --git a/public/scripts/templates/macros.html b/public/scripts/templates/macros.html
index 2eb9ca7b7..46336c083 100644
--- a/public/scripts/templates/macros.html
+++ b/public/scripts/templates/macros.html
@@ -4,6 +4,7 @@
- {{pipe}} – only for slash command batching. Replaced with the returned result of the previous command.
- {{newline}} – just inserts a newline.
+ - {{trim}} – trims newlines surrounding this macro.
- {{original}} – global prompts defined in API settings. Only valid in Advanced Definitions prompt overrides.
- {{input}} – the user input
- {{charPrompt}} – the Character's Main Prompt override
From 42e1ade148038a53a09d72bf96cae107e8274469 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Wed, 10 Apr 2024 01:04:12 +0300
Subject: [PATCH 04/16] Add a {{noop}} macro
---
public/scripts/macros.js | 1 +
public/scripts/templates/macros.html | 1 +
2 files changed, 2 insertions(+)
diff --git a/public/scripts/macros.js b/public/scripts/macros.js
index f89197d3f..74c89b715 100644
--- a/public/scripts/macros.js
+++ b/public/scripts/macros.js
@@ -283,6 +283,7 @@ export function evaluateMacros(content, env) {
content = replaceVariableMacros(content);
content = content.replace(/{{newline}}/gi, '\n');
content = content.replace(/\n*{{trim}}\n*/gi, '');
+ content = content.replace(/{{noop}}/gi, '');
content = content.replace(/{{input}}/gi, () => String($('#send_textarea').val()));
// Substitute passed-in variables
diff --git a/public/scripts/templates/macros.html b/public/scripts/templates/macros.html
index 46336c083..dbb50db80 100644
--- a/public/scripts/templates/macros.html
+++ b/public/scripts/templates/macros.html
@@ -5,6 +5,7 @@
- {{pipe}} – only for slash command batching. Replaced with the returned result of the previous command.
- {{newline}} – just inserts a newline.
- {{trim}} – trims newlines surrounding this macro.
+ - {{noop}} – no operation, just an empty string.
- {{original}} – global prompts defined in API settings. Only valid in Advanced Definitions prompt overrides.
- {{input}} – the user input
- {{charPrompt}} – the Character's Main Prompt override
From b8b49f001229aa40f7605b0582852c2fbac1291b Mon Sep 17 00:00:00 2001
From: kingbri
Date: Tue, 9 Apr 2024 22:08:46 -0400
Subject: [PATCH 05/16] TextgenSettings: Fix JSON schema fallback
Did not fall back if the provided string was empty, resulting in
errors
Signed-off-by: kingbri
---
public/scripts/textgen-settings.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/scripts/textgen-settings.js b/public/scripts/textgen-settings.js
index f871434a3..4f8156a38 100644
--- a/public/scripts/textgen-settings.js
+++ b/public/scripts/textgen-settings.js
@@ -568,7 +568,7 @@ jQuery(function () {
const json_schema_string = String($(this).val());
try {
- settings.json_schema = JSON.parse(json_schema_string ?? '{}');
+ settings.json_schema = JSON.parse(json_schema_string || '{}');
} catch {
// Ignore errors from here
}
From 540cddf300389b92b86f948427312422769c0e8e Mon Sep 17 00:00:00 2001
From: based
Date: Wed, 10 Apr 2024 14:24:43 +1000
Subject: [PATCH 06/16] new turbo model
---
public/index.html | 12 ++++++++----
public/scripts/extensions/caption/index.js | 5 +++--
public/scripts/extensions/shared.js | 4 ++--
public/scripts/openai.js | 5 +++--
4 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/public/index.html b/public/index.html
index b2916a859..df5a56257 100644
--- a/public/index.html
+++ b/public/index.html
@@ -2404,16 +2404,20 @@
+