Stable Diffusion: dedicated LLM connection profile for image prompt generation Reviewed-by: auto-review

849a7483b7514b84dd48cb8e8e63362bfba6ff82

permissionBRICK <permissionBRICK@gmail.com>

2 files changed, +55 -2Ignore whitespace
public/scripts/extensions/stable-diffusion/index.js+52 -2
@@ -44,7 +44,7 @@ import {
44import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.js';44import { getMessageTimeStamp, humanizedDateTime } from '../../RossAscends-mods.js';
45import { SECRET_KEYS, secret_state } from '../../secrets.js';45import { SECRET_KEYS, secret_state } from '../../secrets.js';
46import { getNovelAnlas, getNovelUnlimitedImageGeneration, loadNovelSubscriptionData } from '../../nai-settings.js';46import { getNovelAnlas, getNovelUnlimitedImageGeneration, loadNovelSubscriptionData } from '../../nai-settings.js';
47import { getMultimodalCaption } from '../shared.js';47import { ConnectionManagerRequestService, getMultimodalCaption } from '../shared.js';
48import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';48import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
49import { SlashCommand } from '../../slash-commands/SlashCommand.js';49import { SlashCommand } from '../../slash-commands/SlashCommand.js';
50import {50import {
@@ -365,6 +365,9 @@ const defaultSettings = {
365 settings_preset_primary: null,365 settings_preset_primary: null,
366 settings_preset_secondary: null,366 settings_preset_secondary: null,
367 settings_fallback_enabled: false,367 settings_fallback_enabled: false,
368
369 // Dedicated LLM connection profile for image-prompt generation ('' = use active model)
370 prompt_generation_profile: '',
368};371};
369372
370/**373/**
@@ -534,6 +537,34 @@ function toggleSourceControls() {
534 });537 });
535}538}
536539
540let promptGenerationProfileDropdownInitialized = false;
541
542/**
543 * Populates the dedicated prompt-generation connection profile dropdown.
544 * Only initializes once to avoid attaching duplicate Connection Manager event listeners
545 * when loadSettings() is called again (e.g. after loading a settings preset).
546 */
547function initPromptGenerationProfileDropdown() {
548 if (promptGenerationProfileDropdownInitialized) {
549 return;
550 }
551
552 try {
553 ConnectionManagerRequestService.handleDropdown(
554 '#sd_prompt_generation_profile',
555 extension_settings.sd.prompt_generation_profile,
556 (profile) => {
557 extension_settings.sd.prompt_generation_profile = profile?.id ?? '';
558 saveSettingsDebounced();
559 },
560 );
561 promptGenerationProfileDropdownInitialized = true;
562 } catch (error) {
563 // Connection Manager may be unavailable/disabled; leave the dropdown empty in that case.
564 console.warn('SD: could not populate prompt-generation profile dropdown', error);
565 }
566}
567
537async function loadSettings() {568async function loadSettings() {
538 // Initialize settings569 // Initialize settings
539 if (Object.keys(extension_settings.sd).length === 0) {570 if (Object.keys(extension_settings.sd).length === 0) {
@@ -661,6 +692,8 @@ async function loadSettings() {
661 const resolutionId = getClosestKnownResolution();692 const resolutionId = getClosestKnownResolution();
662 $('#sd_resolution').val(resolutionId);693 $('#sd_resolution').val(resolutionId);
663694
695 initPromptGenerationProfileDropdown();
696
664 toggleSourceControls();697 toggleSourceControls();
665 addPromptTemplates();698 addPromptTemplates();
666 registerFunctionTool();699 registerFunctionTool();
@@ -3421,7 +3454,24 @@ function getUserAvatarUrl() {
3421 */3454 */
3422async function generatePrompt(quietPrompt) {3455async function generatePrompt(quietPrompt) {
3423 const toast = toastr.info('Generating image prompt with an LLM...', 'Image Generation');3456 const toast = toastr.info('Generating image prompt with an LLM...', 'Image Generation');
3424 const reply = await generateQuietPrompt({ quietPrompt });3457 let reply;
3458 const profileId = extension_settings.sd.prompt_generation_profile;
3459
3460 if (profileId) {
3461 try {
3462 // Use the chosen Connection Manager profile (non-streaming) regardless of the active model.
3463 // 1024 tokens is a sensible default cap for an image-prompt description.
3464 const data = await ConnectionManagerRequestService.sendRequest(profileId, quietPrompt, 1024);
3465 // Non-streaming requests resolve to ExtractedData ({ content, reasoning }); extract the plain text.
3466 reply = typeof data === 'object' && data !== null ? String(data.content ?? '') : '';
3467 } catch (err) {
3468 console.warn('SD: prompt-generation profile failed, falling back to active model', err);
3469 reply = await generateQuietPrompt({ quietPrompt });
3470 }
3471 } else {
3472 reply = await generateQuietPrompt({ quietPrompt });
3473 }
3474
3425 const processedReply = processReply(reply);3475 const processedReply = processReply(reply);
3426 toastr.clear(toast);3476 toastr.clear(toast);
34273477
public/scripts/extensions/stable-diffusion/settings.html+3 -0
@@ -39,6 +39,9 @@
39 <input id="sd_minimal_prompt_processing" type="checkbox" />39 <input id="sd_minimal_prompt_processing" type="checkbox" />
40 <span data-i18n="sd_minimal_prompt_processing_txt">Minimal response prompt processing</span>40 <span data-i18n="sd_minimal_prompt_processing_txt">Minimal response prompt processing</span>
41 </label>41 </label>
42 <label for="sd_prompt_generation_profile" data-i18n="Prompt generation connection profile">Prompt generation connection profile</label>
43 <select id="sd_prompt_generation_profile" class="text_pole"></select>
44 <small data-i18n="sd_prompt_generation_profile_small">Connection profile always used to generate the image prompt text. Leave empty to use the currently active model.</small>
42 <hr>45 <hr>
43 <h4 data-i18n="Settings Presets & Fallback">Settings Presets &amp; Fallback</h4>46 <h4 data-i18n="Settings Presets & Fallback">Settings Presets &amp; Fallback</h4>
44 <small data-i18n="sd_settings_presets_small">Save the current backend/connection settings (source, model, sampler, dimensions, etc.) as Primary or Secondary presets and load them back later. Prompt templates, styles, and custom entries are not included.</small>47 <small data-i18n="sd_settings_presets_small">Save the current backend/connection settings (source, model, sampler, dimensions, etc.) as Primary or Secondary presets and load them back later. Prompt templates, styles, and custom entries are not included.</small>