mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Add support for FAL.AI as image gen provider
This commit is contained in:
		@@ -81,6 +81,7 @@ const sources = {
 | 
			
		||||
    huggingface: 'huggingface',
 | 
			
		||||
    nanogpt: 'nanogpt',
 | 
			
		||||
    bfl: 'bfl',
 | 
			
		||||
    falai: 'falai',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const initiators = {
 | 
			
		||||
@@ -1169,6 +1170,10 @@ async function onBflKeyClick() {
 | 
			
		||||
    return onApiKeyClick('BFL API Key:', SECRET_KEYS.BFL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function onFalaiKeyClick() {
 | 
			
		||||
    return onApiKeyClick('FALAI API Key:', SECRET_KEYS.FALAI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onBflUpsamplingInput() {
 | 
			
		||||
    extension_settings.sd.bfl_upsampling = !!$('#sd_bfl_upsampling').prop('checked');
 | 
			
		||||
    saveSettingsDebounced();
 | 
			
		||||
@@ -1707,6 +1712,9 @@ async function loadModels() {
 | 
			
		||||
        case sources.bfl:
 | 
			
		||||
            models = await loadBflModels();
 | 
			
		||||
            break;
 | 
			
		||||
        case sources.falai:
 | 
			
		||||
            models = await loadFalaiModels();
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const model of models) {
 | 
			
		||||
@@ -1744,6 +1752,21 @@ async function loadBflModels() {
 | 
			
		||||
    ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function loadFalaiModels() {
 | 
			
		||||
    $('#sd_falai_key').toggleClass('success', !!secret_state[SECRET_KEYS.FALAI]);
 | 
			
		||||
 | 
			
		||||
    const result = await fetch('/api/sd/falai/models', {
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
        headers: getRequestHeaders(),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (result.ok) {
 | 
			
		||||
        return await result.json();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function loadPollinationsModels() {
 | 
			
		||||
    const result = await fetch('/api/sd/pollinations/models', {
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
@@ -2081,6 +2104,9 @@ async function loadSchedulers() {
 | 
			
		||||
        case sources.bfl:
 | 
			
		||||
            schedulers = ['N/A'];
 | 
			
		||||
            break;
 | 
			
		||||
        case sources.falai:
 | 
			
		||||
            schedulers = ['N/A'];
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const scheduler of schedulers) {
 | 
			
		||||
@@ -2735,6 +2761,9 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP
 | 
			
		||||
            case sources.bfl:
 | 
			
		||||
                result = await generateBflImage(prefixedPrompt, signal);
 | 
			
		||||
                break;
 | 
			
		||||
            case sources.falai:
 | 
			
		||||
                result = await generateFalaiImage(prefixedPrompt, negativePrompt, signal);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!result.data) {
 | 
			
		||||
@@ -3496,6 +3525,39 @@ async function generateBflImage(prompt, signal) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generates an image using the FAL.AI API.
 | 
			
		||||
 * @param {string} prompt - The main instruction used to guide the image generation.
 | 
			
		||||
 * @param {string} negativePrompt - The negative prompt used to guide the image generation.
 | 
			
		||||
 * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request.
 | 
			
		||||
 * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete.
 | 
			
		||||
 */
 | 
			
		||||
async function generateFalaiImage(prompt, negativePrompt, signal) {
 | 
			
		||||
    const result = await fetch('/api/sd/falai/generate', {
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
        headers: getRequestHeaders(),
 | 
			
		||||
        signal: signal,
 | 
			
		||||
        body: JSON.stringify({
 | 
			
		||||
            prompt: prompt,
 | 
			
		||||
            negative_prompt: negativePrompt,
 | 
			
		||||
            model: extension_settings.sd.model,
 | 
			
		||||
            steps: clamp(extension_settings.sd.steps, 1, 50),
 | 
			
		||||
            guidance: clamp(extension_settings.sd.scale, 1.5, 5),
 | 
			
		||||
            width: clamp(extension_settings.sd.width, 256, 1440),
 | 
			
		||||
            height: clamp(extension_settings.sd.height, 256, 1440),
 | 
			
		||||
            seed: extension_settings.sd.seed >= 0 ? extension_settings.sd.seed : undefined,
 | 
			
		||||
        }),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (result.ok) {
 | 
			
		||||
        const data = await result.json();
 | 
			
		||||
        return { format: 'jpg', data: data.image };
 | 
			
		||||
    } else {
 | 
			
		||||
        const text = await result.text();
 | 
			
		||||
        throw new Error(text);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function onComfyOpenWorkflowEditorClick() {
 | 
			
		||||
    let workflow = await (await fetch('/api/sd/comfy/workflow', {
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
@@ -3782,6 +3844,8 @@ function isValidState() {
 | 
			
		||||
            return secret_state[SECRET_KEYS.NANOGPT];
 | 
			
		||||
        case sources.bfl:
 | 
			
		||||
            return secret_state[SECRET_KEYS.BFL];
 | 
			
		||||
        case sources.falai:
 | 
			
		||||
            return secret_state[SECRET_KEYS.FALAI];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -4443,6 +4507,7 @@ jQuery(async () => {
 | 
			
		||||
    $('#sd_function_tool').on('input', onFunctionToolInput);
 | 
			
		||||
    $('#sd_bfl_key').on('click', onBflKeyClick);
 | 
			
		||||
    $('#sd_bfl_upsampling').on('input', onBflUpsamplingInput);
 | 
			
		||||
    $('#sd_falai_key').on('click', onFalaiKeyClick);
 | 
			
		||||
 | 
			
		||||
    if (!CSS.supports('field-sizing', 'content')) {
 | 
			
		||||
        $('.sd_settings .inline-drawer-toggle').on('click', function () {
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,7 @@
 | 
			
		||||
                <option value="auto">Stable Diffusion Web UI (AUTOMATIC1111)</option>
 | 
			
		||||
                <option value="horde">Stable Horde</option>
 | 
			
		||||
                <option value="togetherai">TogetherAI</option>
 | 
			
		||||
                <option value="falai">FAL.AI</option>
 | 
			
		||||
            </select>
 | 
			
		||||
            <div data-sd-source="auto">
 | 
			
		||||
                <label for="sd_auto_url">SD Web UI URL</label>
 | 
			
		||||
@@ -256,6 +257,20 @@
 | 
			
		||||
                </label>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div data-sd-source="falai">
 | 
			
		||||
                <div class="flex-container flexnowrap alignItemsBaseline marginBot5">
 | 
			
		||||
                    <a href="https://fal.ai/dashboard" target="_blank" rel="noopener noreferrer">
 | 
			
		||||
                        <strong data-i18n="API Key">API Key</strong>
 | 
			
		||||
                        <i class="fa-solid fa-share-from-square"></i>
 | 
			
		||||
                    </a>
 | 
			
		||||
                    <span class="expander"></span>
 | 
			
		||||
                    <div id="sd_falai_key" class="menu_button menu_button_icon">
 | 
			
		||||
                        <i class="fa-fw fa-solid fa-key"></i>
 | 
			
		||||
                        <span data-i18n="Click to set">Click to set</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="flex-container">
 | 
			
		||||
                <div class="flex1">
 | 
			
		||||
                    <label for="sd_model" data-i18n="Model">Model</label>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user