Merge branch 'staging' into regex

This commit is contained in:
Cohee
2025-05-26 21:13:13 +03:00
93 changed files with 3110 additions and 847 deletions

View File

@@ -408,13 +408,17 @@ jQuery(async function () {
// Handle multimodal sources
if (settings.source === 'multimodal') {
const api = settings.multimodal_api;
const altEndpointEnabled = settings.alt_endpoint_enabled;
const altEndpointUrl = settings.alt_endpoint_url;
// APIs that support reverse proxy
const reverseProxyApis = {
'openai': SECRET_KEYS.OPENAI,
'mistral': SECRET_KEYS.MISTRALAI,
'google': SECRET_KEYS.MAKERSUITE,
'vertexai': SECRET_KEYS.VERTEXAI,
'anthropic': SECRET_KEYS.CLAUDE,
'xai': SECRET_KEYS.XAI,
};
if (reverseProxyApis[api]) {
@@ -428,7 +432,6 @@ jQuery(async function () {
'zerooneai': SECRET_KEYS.ZEROONEAI,
'groq': SECRET_KEYS.GROQ,
'cohere': SECRET_KEYS.COHERE,
'xai': SECRET_KEYS.XAI,
};
if (chatCompletionApis[api] && secret_state[chatCompletionApis[api]]) {
@@ -443,12 +446,16 @@ jQuery(async function () {
'vllm': textgen_types.VLLM,
};
if (textCompletionApis[api] && textgenerationwebui_settings.server_urls[textCompletionApis[api]]) {
if (textCompletionApis[api] && altEndpointEnabled && altEndpointUrl) {
return true;
}
if (textCompletionApis[api] && !altEndpointEnabled && textgenerationwebui_settings.server_urls[textCompletionApis[api]]) {
return true;
}
// Custom API doesn't need additional checks
if (api === 'custom') {
if (api === 'custom' || api === 'pollinations') {
return true;
}
}
@@ -579,6 +586,14 @@ jQuery(async function () {
extension_settings.caption.multimodal_model = String($('#caption_multimodal_model').val());
saveSettingsDebounced();
});
$('#caption_altEndpoint_url').val(extension_settings.caption.alt_endpoint_url).on('input', () => {
extension_settings.caption.alt_endpoint_url = String($('#caption_altEndpoint_url').val());
saveSettingsDebounced();
});
$('#caption_altEndpoint_enabled').prop('checked', !!(extension_settings.caption.alt_endpoint_enabled)).on('input', () => {
extension_settings.caption.alt_endpoint_enabled = !!$('#caption_altEndpoint_enabled').prop('checked');
saveSettingsDebounced();
});
const onMessageEvent = async (index) => {
if (!extension_settings.caption.auto_mode) {

View File

@@ -22,6 +22,7 @@
<option value="cohere">Cohere</option>
<option value="custom" data-i18n="Custom (OpenAI-compatible)">Custom (OpenAI-compatible)</option>
<option value="google">Google AI Studio</option>
<option value="vertexai">Google Vertex AI</option>
<option value="groq">Groq</option>
<option value="koboldcpp">KoboldCpp</option>
<option value="llamacpp">llama.cpp</option>
@@ -30,6 +31,7 @@
<option value="openai">OpenAI</option>
<option value="openrouter">OpenRouter</option>
<option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option>
<option value="pollinations">Pollinations</option>
<option value="vllm">vLLM</option>
<option value="xai">xAI (Grok)</option>
</select>
@@ -46,6 +48,8 @@
<option data-type="mistral" value="mistral-large-pixtral-2411">mistral-large-pixtral-2411</option>
<option data-type="mistral" value="mistral-small-2503">mistral-small-2503</option>
<option data-type="mistral" value="mistral-small-latest">mistral-small-latest</option>
<option data-type="mistral" value="mistral-medium-latest">mistral-medium-latest</option>
<option data-type="mistral" value="mistral-medium-2505">mistral-medium-2505</option>
<option data-type="zerooneai" value="yi-vision">yi-vision</option>
<option data-type="openai" value="gpt-4.1">gpt-4.1</option>
<option data-type="openai" value="gpt-4.1-2025-04-14">gpt-4.1-2025-04-14</option>
@@ -67,6 +71,10 @@
<option data-type="openai" value="o4-mini-2025-04-16">o4-mini-2025-04-16</option>
<option data-type="openai" value="gpt-4.5-preview">gpt-4.5-preview</option>
<option data-type="openai" value="gpt-4.5-preview-2025-02-27">gpt-4.5-preview-2025-02-27</option>
<option data-type="anthropic" value="claude-opus-4-0">claude-opus-4-0</option>
<option data-type="anthropic" value="claude-opus-4-20250514">claude-opus-4-20250514</option>
<option data-type="anthropic" value="claude-sonnet-4-0">claude-sonnet-4-0</option>
<option data-type="anthropic" value="claude-sonnet-4-20250514">claude-sonnet-4-20250514</option>
<option data-type="anthropic" value="claude-3-7-sonnet-latest">claude-3-7-sonnet-latest</option>
<option data-type="anthropic" value="claude-3-7-sonnet-20250219">claude-3-7-sonnet-20250219</option>
<option data-type="anthropic" value="claude-3-5-sonnet-latest">claude-3-5-sonnet-latest</option>
@@ -77,8 +85,10 @@
<option data-type="anthropic" value="claude-3-opus-20240229">claude-3-opus-20240229</option>
<option data-type="anthropic" value="claude-3-sonnet-20240229">claude-3-sonnet-20240229</option>
<option data-type="anthropic" value="claude-3-haiku-20240307">claude-3-haiku-20240307</option>
<option data-type="google" value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option>
<option data-type="google" value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option>
<option data-type="google" value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option>
<option data-type="google" value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option>
<option data-type="google" value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option>
<option data-type="google" value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05 → 2.5-pro-exp-03-25</option>
<option data-type="google" value="gemini-2.0-pro-exp">gemini-2.0-pro-exp → 2.5-pro-exp-03-25</option>
@@ -106,6 +116,12 @@
<option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option>
<option data-type="google" value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option>
<option data-type="google" value="learnlm-1.5-pro-experimental">learnlm-1.5-pro-experimental</option>
<option data-type="vertexai" value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option>
<option data-type="vertexai" value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option>
<option data-type="vertexai" value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option>
<option data-type="vertexai" value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option>
<option data-type="vertexai" value="gemini-2.0-flash-001">gemini-2.0-flash-001</option>
<option data-type="vertexai" value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option>
<option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option>
<option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option>
<option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option>
@@ -148,12 +164,24 @@
<option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option>
<option data-type="xai" value="grok-2-vision-1212">grok-2-vision-1212</option>
<option data-type="xai" value="grok-vision-beta">grok-vision-beta</option>
<option data-type="pollinations" value="openai">openai</option>
<option data-type="pollinations" value="openai-fast">openai-fast</option>
<option data-type="pollinations" value="openai-large">openai-large</option>
<option data-type="pollinations" value="openai-roblox">openai-roblox</option>
<option data-type="pollinations" value="mistral">mistral</option>
<option data-type="pollinations" value="unity">unity</option>
<option data-type="pollinations" value="mirexa">mirexa</option>
<option data-type="pollinations" value="searchgpt">searchgpt</option>
<option data-type="pollinations" value="evil">evil</option>
<option data-type="pollinations" value="phi">phi</option>
<option data-type="pollinations" value="sur">sur</option>
<option data-type="pollinations" value="bidara">bidara</option>
</select>
</div>
<div data-type="ollama">
The model must be downloaded first! Do it with the <code>ollama pull</code> command or <a href="#" id="caption_ollama_pull">click here</a>.
</div>
<label data-type="openai,anthropic,google,mistral" class="checkbox_label flexBasis100p" for="caption_allow_reverse_proxy" title="Allow using reverse proxy if defined and valid.">
<label data-type="openai,anthropic,google,vertexai,mistral,xai" class="checkbox_label flexBasis100p" for="caption_allow_reverse_proxy" title="Allow using reverse proxy if defined and valid.">
<input id="caption_allow_reverse_proxy" type="checkbox" class="checkbox">
<span data-i18n="Allow reverse proxy">Allow reverse proxy</span>
</label>
@@ -161,6 +189,16 @@
<small><b data-i18n="Hint:">Hint:</b> <span data-i18n="Set your API keys and endpoints in the 'API Connections' tab first.">Set your API keys and endpoints in the 'API Connections' tab first.</span></small>
</div>
</div>
<div data-type="koboldcpp,ollama,vllm,llamacpp,ooba" class="flex-container flexFlowColumn">
<label for="caption_altEndpoint_enabled" class="checkbox_label">
<input id="caption_altEndpoint_enabled" type="checkbox">
<span data-i18n="Use secondary URL">Use secondary URL</span>
</label>
<label for="caption_altEndpoint_url" data-i18n="Secondary captioning endpoint URL">
Secondary captioning endpoint URL
</label>
<input id="caption_altEndpoint_url" class="text_pole" type="text" placeholder="e.g. http://localhost:5001" />
</div>
<div id="caption_prompt_block">
<label for="caption_prompt" data-i18n="Caption Prompt">Caption Prompt</label>
<textarea id="caption_prompt" class="text_pole" rows="1" placeholder="&lt; Use default &gt;">{{PROMPT_DEFAULT}}</textarea>

View File

@@ -710,7 +710,7 @@ async function listGalleryCommand(args) {
delete context.extensionSettings.gallery.folders[avatar];
context.saveSettingsDebounced();
});
eventSource.on('charManagementDropdown', (selectedOptionId) => {
eventSource.on(event_types.CHARACTER_MANAGEMENT_DROPDOWN, (selectedOptionId) => {
if (selectedOptionId === 'show_char_gallery') {
showCharGallery();
}

View File

@@ -28,6 +28,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '
import { MacrosParser } from '../../macros.js';
import { countWebLlmTokens, generateWebLlmChatPrompt, getWebLlmContextSize, isWebLlmSupported } from '../shared.js';
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
import { removeReasoningFromString } from '../../reasoning.js';
export { MODULE_NAME };
const MODULE_NAME = '1_memory';
@@ -504,7 +505,7 @@ async function summarizeCallback(args, text) {
case summary_sources.extras:
return await callExtrasSummarizeAPI(text);
case summary_sources.main:
return await generateRaw(text, '', false, false, prompt, extension_settings.memory.overrideResponseLength);
return removeReasoningFromString(await generateRaw(text, '', false, false, prompt, extension_settings.memory.overrideResponseLength));
case summary_sources.webllm: {
const messages = [{ role: 'system', content: prompt }, { role: 'user', content: text }].filter(m => m.content);
const params = extension_settings.memory.overrideResponseLength > 0 ? { max_tokens: extension_settings.memory.overrideResponseLength } : {};
@@ -699,7 +700,8 @@ async function summarizeChatMain(context, force, skipWIAN) {
return null;
}
summary = await generateRaw(rawPrompt, '', false, false, prompt, extension_settings.memory.overrideResponseLength);
const rawSummary = await generateRaw(rawPrompt, '', false, false, prompt, extension_settings.memory.overrideResponseLength);
summary = removeReasoningFromString(rawSummary);
index = lastUsedIndex;
} finally {
inApiCall = false;

View File

@@ -15,14 +15,14 @@ import { createThumbnail, isValidUrl } from '../utils.js';
*/
export async function getMultimodalCaption(base64Img, prompt) {
const useReverseProxy =
(['openai', 'anthropic', 'google', 'mistral'].includes(extension_settings.caption.multimodal_api))
(['openai', 'anthropic', 'google', 'mistral', 'vertexai', 'xai'].includes(extension_settings.caption.multimodal_api))
&& extension_settings.caption.allow_reverse_proxy
&& oai_settings.reverse_proxy
&& isValidUrl(oai_settings.reverse_proxy);
throwIfInvalidModel(useReverseProxy);
const noPrefix = ['ollama', 'llamacpp'].includes(extension_settings.caption.multimodal_api);
const noPrefix = ['ollama'].includes(extension_settings.caption.multimodal_api);
if (noPrefix && base64Img.startsWith('data:image/')) {
base64Img = base64Img.split(',')[1];
@@ -38,7 +38,8 @@ export async function getMultimodalCaption(base64Img, prompt) {
const isVllm = extension_settings.caption.multimodal_api === 'vllm';
const base64Bytes = base64Img.length * 0.75;
const compressionLimit = 2 * 1024 * 1024;
if ((['google', 'openrouter', 'mistral', 'groq'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) {
const thumbnailNeeded = ['google', 'openrouter', 'mistral', 'groq', 'vertexai'].includes(extension_settings.caption.multimodal_api);
if ((thumbnailNeeded && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) {
const maxSide = 1024;
base64Img = await createThumbnail(base64Img, maxSide, maxSide, 'image/jpeg');
}
@@ -60,7 +61,9 @@ export async function getMultimodalCaption(base64Img, prompt) {
requestBody.model = textgenerationwebui_settings.ollama_model;
}
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OLLAMA];
requestBody.server_url = extension_settings.caption.alt_endpoint_enabled
? extension_settings.caption.alt_endpoint_url
: textgenerationwebui_settings.server_urls[textgen_types.OLLAMA];
}
if (isVllm) {
@@ -68,19 +71,27 @@ export async function getMultimodalCaption(base64Img, prompt) {
requestBody.model = textgenerationwebui_settings.vllm_model;
}
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.VLLM];
requestBody.server_url = extension_settings.caption.alt_endpoint_enabled
? extension_settings.caption.alt_endpoint_url
: textgenerationwebui_settings.server_urls[textgen_types.VLLM];
}
if (isLlamaCpp) {
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP];
requestBody.server_url = extension_settings.caption.alt_endpoint_enabled
? extension_settings.caption.alt_endpoint_url
: textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP];
}
if (isOoba) {
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OOBA];
requestBody.server_url = extension_settings.caption.alt_endpoint_enabled
? extension_settings.caption.alt_endpoint_url
: textgenerationwebui_settings.server_urls[textgen_types.OOBA];
}
if (isKoboldCpp) {
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP];
requestBody.server_url = extension_settings.caption.alt_endpoint_enabled
? extension_settings.caption.alt_endpoint_url
: textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP];
}
if (isCustom) {
@@ -94,11 +105,10 @@ export async function getMultimodalCaption(base64Img, prompt) {
function getEndpointUrl() {
switch (extension_settings.caption.multimodal_api) {
case 'google':
case 'vertexai':
return '/api/google/caption-image';
case 'anthropic':
return '/api/anthropic/caption-image';
case 'llamacpp':
return '/api/backends/text-completions/llamacpp/caption-image';
case 'ollama':
return '/api/backends/text-completions/ollama/caption-image';
default:
@@ -121,71 +131,84 @@ export async function getMultimodalCaption(base64Img, prompt) {
}
function throwIfInvalidModel(useReverseProxy) {
if (extension_settings.caption.multimodal_api === 'openai' && !secret_state[SECRET_KEYS.OPENAI] && !useReverseProxy) {
const altEndpointEnabled = extension_settings.caption.alt_endpoint_enabled;
const altEndpointUrl = extension_settings.caption.alt_endpoint_url;
const multimodalModel = extension_settings.caption.multimodal_model;
const multimodalApi = extension_settings.caption.multimodal_api;
if (altEndpointEnabled && ['llamacpp', 'ooba', 'koboldcpp', 'vllm', 'ollama'].includes(multimodalApi) && !altEndpointUrl) {
throw new Error('Secondary endpoint URL is not set.');
}
if (multimodalApi === 'openai' && !secret_state[SECRET_KEYS.OPENAI] && !useReverseProxy) {
throw new Error('OpenAI API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'openrouter' && !secret_state[SECRET_KEYS.OPENROUTER]) {
if (multimodalApi === 'openrouter' && !secret_state[SECRET_KEYS.OPENROUTER]) {
throw new Error('OpenRouter API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'anthropic' && !secret_state[SECRET_KEYS.CLAUDE] && !useReverseProxy) {
if (multimodalApi === 'anthropic' && !secret_state[SECRET_KEYS.CLAUDE] && !useReverseProxy) {
throw new Error('Anthropic (Claude) API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'zerooneai' && !secret_state[SECRET_KEYS.ZEROONEAI]) {
if (multimodalApi === 'zerooneai' && !secret_state[SECRET_KEYS.ZEROONEAI]) {
throw new Error('01.AI API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'groq' && !secret_state[SECRET_KEYS.GROQ]) {
if (multimodalApi === 'groq' && !secret_state[SECRET_KEYS.GROQ]) {
throw new Error('Groq API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'google' && !secret_state[SECRET_KEYS.MAKERSUITE] && !useReverseProxy) {
if (multimodalApi === 'google' && !secret_state[SECRET_KEYS.MAKERSUITE] && !useReverseProxy) {
throw new Error('Google AI Studio API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'mistral' && !secret_state[SECRET_KEYS.MISTRALAI] && !useReverseProxy) {
if (multimodalApi === 'vertexai' && !secret_state[SECRET_KEYS.VERTEXAI] && !useReverseProxy) {
throw new Error('Google Vertex AI API key is not set.');
}
if (multimodalApi === 'mistral' && !secret_state[SECRET_KEYS.MISTRALAI] && !useReverseProxy) {
throw new Error('Mistral AI API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'cohere' && !secret_state[SECRET_KEYS.COHERE]) {
if (multimodalApi === 'cohere' && !secret_state[SECRET_KEYS.COHERE]) {
throw new Error('Cohere API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'xai' && !secret_state[SECRET_KEYS.XAI]) {
if (multimodalApi === 'xai' && !secret_state[SECRET_KEYS.XAI] && !useReverseProxy) {
throw new Error('xAI API key is not set.');
}
if (extension_settings.caption.multimodal_api === 'ollama' && !textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]) {
if (multimodalApi === 'ollama' && !textgenerationwebui_settings.server_urls[textgen_types.OLLAMA] && !altEndpointEnabled) {
throw new Error('Ollama server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'ollama' && extension_settings.caption.multimodal_model === 'ollama_current' && !textgenerationwebui_settings.ollama_model) {
if (multimodalApi === 'ollama' && multimodalModel === 'ollama_current' && !textgenerationwebui_settings.ollama_model) {
throw new Error('Ollama model is not set.');
}
if (extension_settings.caption.multimodal_api === 'llamacpp' && !textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) {
if (multimodalApi === 'llamacpp' && !textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP] && !altEndpointEnabled) {
throw new Error('LlamaCPP server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'ooba' && !textgenerationwebui_settings.server_urls[textgen_types.OOBA]) {
if (multimodalApi === 'ooba' && !textgenerationwebui_settings.server_urls[textgen_types.OOBA] && !altEndpointEnabled) {
throw new Error('Text Generation WebUI server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'koboldcpp' && !textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]) {
if (multimodalApi === 'koboldcpp' && !textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP] && !altEndpointEnabled) {
throw new Error('KoboldCpp server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'vllm' && !textgenerationwebui_settings.server_urls[textgen_types.VLLM]) {
if (multimodalApi === 'vllm' && !textgenerationwebui_settings.server_urls[textgen_types.VLLM] && !altEndpointEnabled) {
throw new Error('vLLM server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'vllm' && extension_settings.caption.multimodal_model === 'vllm_current' && !textgenerationwebui_settings.vllm_model) {
if (multimodalApi === 'vllm' && multimodalModel === 'vllm_current' && !textgenerationwebui_settings.vllm_model) {
throw new Error('vLLM model is not set.');
}
if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) {
if (multimodalApi === 'custom' && !oai_settings.custom_url) {
throw new Error('Custom API URL is not set.');
}
}

View File

@@ -56,6 +56,8 @@ import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValu
import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js';
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
import { ToolManager } from '../../tool-calling.js';
import { MacrosParser } from '../../macros.js';
import { t } from '../../i18n.js';
export { MODULE_NAME };
@@ -930,6 +932,10 @@ const resolutionOptions = {
sd_res_768x1344: { width: 768, height: 1344, name: '768x1344 (3:4, SDXL)' },
sd_res_1536x640: { width: 1536, height: 640, name: '1536x640 (24:10, SDXL)' },
sd_res_640x1536: { width: 640, height: 1536, name: '640x1536 (10:24, SDXL)' },
sd_res_1536x1024: { width: 1536, height: 1024, name: '1536x1024 (3:2, ChatGPT)' },
sd_res_1024x1536: { width: 1024, height: 1536, name: '1024x1536 (2:3, ChatGPT)' },
sd_res_1024x1792: { width: 1024, height: 1792, name: '1024x1792 (4:7, DALL-E)' },
sd_res_1792x1024: { width: 1792, height: 1024, name: '1792x1024 (7:4, DALL-E)' },
};
function onResolutionChange() {
@@ -1947,8 +1953,9 @@ async function loadDrawthingsModels() {
async function loadOpenAiModels() {
return [
{ value: 'dall-e-3', text: 'DALL-E 3' },
{ value: 'dall-e-2', text: 'DALL-E 2' },
{ value: 'gpt-image-1', text: 'gpt-image-1' },
{ value: 'dall-e-3', text: 'dall-e-3' },
{ value: 'dall-e-2', text: 'dall-e-2' },
];
}
@@ -3250,9 +3257,11 @@ function getNovelParams() {
async function generateOpenAiImage(prompt, signal) {
const dalle2PromptLimit = 1000;
const dalle3PromptLimit = 4000;
const gptImgPromptLimit = 32000;
const isDalle2 = extension_settings.sd.model === 'dall-e-2';
const isDalle3 = extension_settings.sd.model === 'dall-e-3';
const isGptImg = extension_settings.sd.model === 'gpt-image-1';
if (isDalle2 && prompt.length > dalle2PromptLimit) {
prompt = prompt.substring(0, dalle2PromptLimit);
@@ -3262,6 +3271,10 @@ async function generateOpenAiImage(prompt, signal) {
prompt = prompt.substring(0, dalle3PromptLimit);
}
if (isGptImg && prompt.length > gptImgPromptLimit) {
prompt = prompt.substring(0, gptImgPromptLimit);
}
let width = 1024;
let height = 1024;
let aspectRatio = extension_settings.sd.width / extension_settings.sd.height;
@@ -3274,6 +3287,14 @@ async function generateOpenAiImage(prompt, signal) {
width = 1792;
}
if (isGptImg && aspectRatio < 1) {
height = 1536;
}
if (isGptImg && aspectRatio > 1) {
width = 1536;
}
if (isDalle2 && (extension_settings.sd.width <= 512 && extension_settings.sd.height <= 512)) {
width = 512;
height = 512;
@@ -3290,7 +3311,8 @@ async function generateOpenAiImage(prompt, signal) {
n: 1,
quality: isDalle3 ? extension_settings.sd.openai_quality : undefined,
style: isDalle3 ? extension_settings.sd.openai_style : undefined,
response_format: 'b64_json',
response_format: isDalle2 || isDalle3 ? 'b64_json' : undefined,
moderation: isGptImg ? 'low' : undefined,
}),
});
@@ -4528,4 +4550,29 @@ jQuery(async () => {
await loadSettings();
$('body').addClass('sd');
const getMacroValue = ({ isNegative }) => {
if (selected_group || this_chid === undefined) {
return '';
}
const key = getCharaFilename(this_chid);
let characterPrompt = key ? (extension_settings.sd.character_prompts[key] || '') : '';
let negativePrompt = key ? (extension_settings.sd.character_negative_prompts[key] || '') : '';
const context = getContext();
const sharedPromptData = context?.characters[this_chid]?.data?.extensions?.sd_character_prompt;
if (typeof sharedPromptData?.positive === 'string' && !characterPrompt && sharedPromptData.positive) {
characterPrompt = sharedPromptData.positive || '';
}
if (typeof sharedPromptData?.negative === 'string' && !negativePrompt && sharedPromptData.negative) {
negativePrompt = sharedPromptData.negative || '';
}
return isNegative ? negativePrompt : characterPrompt;
};
MacrosParser.registerMacro('charPrefix', () => getMacroValue({ isNegative: false }), t`Character's positive positive Image Generation prompt prefix`);
MacrosParser.registerMacro('charNegativePrefix', () => getMacroValue({ isNegative: true }), t`Character's negative Image Generation prompt prefix`);
});

View File

@@ -45,7 +45,7 @@
<option value="huggingface">HuggingFace Inference API (serverless)</option>
<option value="nanogpt">NanoGPT</option>
<option value="novel">NovelAI Diffusion</option>
<option value="openai">OpenAI (DALL-E)</option>
<option value="openai">OpenAI</option>
<option value="pollinations">Pollinations</option>
<option value="vlad">SD.Next (vladmandic)</option>
<option value="stability">Stability AI</option>

View File

@@ -36,6 +36,7 @@ import { slashCommandReturnHelper } from '../../slash-commands/SlashCommandRetur
import { callGenericPopup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js';
import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js';
import { WebLlmVectorProvider } from './webllm.js';
import { removeReasoningFromString } from '../../reasoning.js';
/**
* @typedef {object} HashedMessage
@@ -260,7 +261,7 @@ async function summarizeExtra(element) {
* @returns {Promise<boolean>} Sucess
*/
async function summarizeMain(element) {
element.text = await generateRaw(element.text, '', false, false, settings.summary_prompt);
element.text = removeReasoningFromString(await generateRaw(element.text, '', false, false, settings.summary_prompt));
return true;
}