Add cancelling of SD gens
| @@ -2289,24 +2289,34 @@ async function generatePicture(initiator, args, trigger, message, callback) { | |||
| 2289 | } | 2289 | } |
| 2290 | 2290 | ||
| 2291 | const dimensions = setTypeSpecificDimensions(generationType); | 2291 | const dimensions = setTypeSpecificDimensions(generationType); |
| 2292 | const abortController = new AbortController(); | ||
| 2292 | let negativePromptPrefix = args?.negative || ''; | 2293 | let negativePromptPrefix = args?.negative || ''; |
| 2293 | let imagePath = ''; | 2294 | let imagePath = ''; |
| 2294 | 2295 | ||
| 2296 | const stopListener = () => abortController.abort('Aborted by user'); | ||
| 2297 | const mesStop = document.getElementById('mes_stop'); | ||
| 2298 | |||
| 2295 | try { | 2299 | try { |
| 2296 | const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); }; | 2300 | const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); }; |
| 2297 | const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives); | 2301 | const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives); |
| 2298 | console.log('Processed image prompt:', prompt); | 2302 | console.log('Processed image prompt:', prompt); |
| 2299 | 2303 | ||
| 2304 | mesStop?.addEventListener('click', stopListener); | ||
| 2300 | context.deactivateSendButtons(); | 2305 | context.deactivateSendButtons(); |
| 2301 | hideSwipeButtons(); | 2306 | hideSwipeButtons(); |
| 2302 | 2307 | ||
| 2303 | imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator); | 2308 | if (typeof args?._abortController?.addEventListener === 'function') { |
| 2309 | args._abortController.addEventListener('abort', stopListener); | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator, abortController.signal); | ||
| 2304 | } catch (err) { | 2313 | } catch (err) { |
| 2305 | console.trace(err); | 2314 | console.trace(err); |
| 2306 | throw new Error('SD prompt text generation failed.'); | 2315 | throw new Error('SD prompt text generation failed.'); |
| 2307 | } | 2316 | } |
| 2308 | finally { | 2317 | finally { |
| 2309 | restoreOriginalDimensions(dimensions); | 2318 | restoreOriginalDimensions(dimensions); |
| 2319 | mesStop?.removeEventListener('click', stopListener); | ||
| 2310 | context.activateSendButtons(); | 2320 | context.activateSendButtons(); |
| 2311 | showSwipeButtons(); | 2321 | showSwipeButtons(); |
| 2312 | } | 2322 | } |
| @@ -2521,9 +2531,10 @@ async function generatePrompt(quietPrompt) { | |||
| 2521 | * @param {string} characterName Name of the character | 2531 | * @param {string} characterName Name of the character |
| 2522 | * @param {function} callback Callback function to be called after image generation | 2532 | * @param {function} callback Callback function to be called after image generation |
| 2523 | * @param {string} initiator The initiator of the image generation | 2533 | * @param {string} initiator The initiator of the image generation |
| 2534 | * @param {AbortSignal} signal Abort signal to cancel the request | ||
| 2524 | * @returns | 2535 | * @returns |
| 2525 | */ | 2536 | */ |
| 2526 | async function sendGenerationRequest(generationType, prompt, additionalNegativePrefix, characterName, callback, initiator) { | 2537 | async function sendGenerationRequest(generationType, prompt, additionalNegativePrefix, characterName, callback, initiator, signal) { |
| 2527 | const noCharPrefix = [generationMode.FREE, generationMode.BACKGROUND, generationMode.USER, generationMode.USER_MULTIMODAL, generationMode.FREE_EXTENDED]; | 2538 | const noCharPrefix = [generationMode.FREE, generationMode.BACKGROUND, generationMode.USER, generationMode.USER_MULTIMODAL, generationMode.FREE_EXTENDED]; |
| 2528 | const prefix = noCharPrefix.includes(generationType) | 2539 | const prefix = noCharPrefix.includes(generationType) |
| 2529 | ? extension_settings.sd.prompt_prefix | 2540 | ? extension_settings.sd.prompt_prefix |
| @@ -2541,37 +2552,37 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP | |||
| 2541 | try { | 2552 | try { |
| 2542 | switch (extension_settings.sd.source) { | 2553 | switch (extension_settings.sd.source) { |
| 2543 | case sources.extras: | 2554 | case sources.extras: |
| 2544 | result = await generateExtrasImage(prefixedPrompt, negativePrompt); | 2555 | result = await generateExtrasImage(prefixedPrompt, negativePrompt, signal); |
| 2545 | break; | 2556 | break; |
| 2546 | case sources.horde: | 2557 | case sources.horde: |
| 2547 | result = await generateHordeImage(prefixedPrompt, negativePrompt); | 2558 | result = await generateHordeImage(prefixedPrompt, negativePrompt, signal); |
| 2548 | break; | 2559 | break; |
| 2549 | case sources.vlad: | 2560 | case sources.vlad: |
| 2550 | result = await generateAutoImage(prefixedPrompt, negativePrompt); | 2561 | result = await generateAutoImage(prefixedPrompt, negativePrompt, signal); |
| 2551 | break; | 2562 | break; |
| 2552 | case sources.drawthings: | 2563 | case sources.drawthings: |
| 2553 | result = await generateDrawthingsImage(prefixedPrompt, negativePrompt); | 2564 | result = await generateDrawthingsImage(prefixedPrompt, negativePrompt, signal); |
| 2554 | break; | 2565 | break; |
| 2555 | case sources.auto: | 2566 | case sources.auto: |
| 2556 | result = await generateAutoImage(prefixedPrompt, negativePrompt); | 2567 | result = await generateAutoImage(prefixedPrompt, negativePrompt, signal); |
| 2557 | break; | 2568 | break; |
| 2558 | case sources.novel: | 2569 | case sources.novel: |
| 2559 | result = await generateNovelImage(prefixedPrompt, negativePrompt); | 2570 | result = await generateNovelImage(prefixedPrompt, negativePrompt, signal); |
| 2560 | break; | 2571 | break; |
| 2561 | case sources.openai: | 2572 | case sources.openai: |
| 2562 | result = await generateOpenAiImage(prefixedPrompt); | 2573 | result = await generateOpenAiImage(prefixedPrompt, signal); |
| 2563 | break; | 2574 | break; |
| 2564 | case sources.comfy: | 2575 | case sources.comfy: |
| 2565 | result = await generateComfyImage(prefixedPrompt, negativePrompt); | 2576 | result = await generateComfyImage(prefixedPrompt, negativePrompt, signal); |
| 2566 | break; | 2577 | break; |
| 2567 | case sources.togetherai: | 2578 | case sources.togetherai: |
| 2568 | result = await generateTogetherAIImage(prefixedPrompt, negativePrompt); | 2579 | result = await generateTogetherAIImage(prefixedPrompt, negativePrompt, signal); |
| 2569 | break; | 2580 | break; |
| 2570 | case sources.pollinations: | 2581 | case sources.pollinations: |
| 2571 | result = await generatePollinationsImage(prefixedPrompt, negativePrompt); | 2582 | result = await generatePollinationsImage(prefixedPrompt, negativePrompt, signal); |
| 2572 | break; | 2583 | break; |
| 2573 | case sources.stability: | 2584 | case sources.stability: |
| 2574 | result = await generateStabilityImage(prefixedPrompt, negativePrompt); | 2585 | result = await generateStabilityImage(prefixedPrompt, negativePrompt, signal); |
| 2575 | break; | 2586 | break; |
| 2576 | } | 2587 | } |
| 2577 | 2588 | ||
| @@ -2600,12 +2611,14 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP | |||
| 2600 | * Generates an image using the TogetherAI API. | 2611 | * Generates an image using the TogetherAI API. |
| 2601 | * @param {string} prompt - The main instruction used to guide the image generation. | 2612 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2602 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2613 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2614 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2603 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2615 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2604 | */ | 2616 | */ |
| 2605 | async function generateTogetherAIImage(prompt, negativePrompt) { | 2617 | async function generateTogetherAIImage(prompt, negativePrompt, signal) { |
| 2606 | const result = await fetch('/api/sd/together/generate', { | 2618 | const result = await fetch('/api/sd/together/generate', { |
| 2607 | method: 'POST', | 2619 | method: 'POST', |
| 2608 | headers: getRequestHeaders(), | 2620 | headers: getRequestHeaders(), |
| 2621 | signal: signal, | ||
| 2609 | body: JSON.stringify({ | 2622 | body: JSON.stringify({ |
| 2610 | prompt: prompt, | 2623 | prompt: prompt, |
| 2611 | negative_prompt: negativePrompt, | 2624 | negative_prompt: negativePrompt, |
| @@ -2630,12 +2643,14 @@ async function generateTogetherAIImage(prompt, negativePrompt) { | |||
| 2630 | * Generates an image using the Pollinations API. | 2643 | * Generates an image using the Pollinations API. |
| 2631 | * @param {string} prompt - The main instruction used to guide the image generation. | 2644 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2632 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2645 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2646 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2633 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2647 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2634 | */ | 2648 | */ |
| 2635 | async function generatePollinationsImage(prompt, negativePrompt) { | 2649 | async function generatePollinationsImage(prompt, negativePrompt, signal) { |
| 2636 | const result = await fetch('/api/sd/pollinations/generate', { | 2650 | const result = await fetch('/api/sd/pollinations/generate', { |
| 2637 | method: 'POST', | 2651 | method: 'POST', |
| 2638 | headers: getRequestHeaders(), | 2652 | headers: getRequestHeaders(), |
| 2653 | signal: signal, | ||
| 2639 | body: JSON.stringify({ | 2654 | body: JSON.stringify({ |
| 2640 | prompt: prompt, | 2655 | prompt: prompt, |
| 2641 | negative_prompt: negativePrompt, | 2656 | negative_prompt: negativePrompt, |
| @@ -2662,9 +2677,10 @@ async function generatePollinationsImage(prompt, negativePrompt) { | |||
| 2662 | * | 2677 | * |
| 2663 | * @param {string} prompt - The main instruction used to guide the image generation. | 2678 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2664 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2679 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2680 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2665 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2681 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2666 | */ | 2682 | */ |
| 2667 | async function generateExtrasImage(prompt, negativePrompt) { | 2683 | async function generateExtrasImage(prompt, negativePrompt, signal) { |
| 2668 | const url = new URL(getApiUrl()); | 2684 | const url = new URL(getApiUrl()); |
| 2669 | url.pathname = '/api/image'; | 2685 | url.pathname = '/api/image'; |
| 2670 | const result = await doExtrasFetch(url, { | 2686 | const result = await doExtrasFetch(url, { |
| @@ -2672,6 +2688,7 @@ async function generateExtrasImage(prompt, negativePrompt) { | |||
| 2672 | headers: { | 2688 | headers: { |
| 2673 | 'Content-Type': 'application/json', | 2689 | 'Content-Type': 'application/json', |
| 2674 | }, | 2690 | }, |
| 2691 | signal: signal, | ||
| 2675 | body: JSON.stringify({ | 2692 | body: JSON.stringify({ |
| 2676 | prompt: prompt, | 2693 | prompt: prompt, |
| 2677 | sampler: extension_settings.sd.sampler, | 2694 | sampler: extension_settings.sd.sampler, |
| @@ -2739,9 +2756,10 @@ function getClosestAspectRatio(width, height) { | |||
| 2739 | * Generates an image using Stability AI. | 2756 | * Generates an image using Stability AI. |
| 2740 | * @param {string} prompt - The main instruction used to guide the image generation. | 2757 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2741 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2758 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2759 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2742 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2760 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2743 | */ | 2761 | */ |
| 2744 | async function generateStabilityImage(prompt, negativePrompt) { | 2762 | async function generateStabilityImage(prompt, negativePrompt, signal) { |
| 2745 | const IMAGE_FORMAT = 'png'; | 2763 | const IMAGE_FORMAT = 'png'; |
| 2746 | const PROMPT_LIMIT = 10000; | 2764 | const PROMPT_LIMIT = 10000; |
| 2747 | 2765 | ||
| @@ -2749,6 +2767,7 @@ async function generateStabilityImage(prompt, negativePrompt) { | |||
| 2749 | const response = await fetch('/api/sd/stability/generate', { | 2767 | const response = await fetch('/api/sd/stability/generate', { |
| 2750 | method: 'POST', | 2768 | method: 'POST', |
| 2751 | headers: getRequestHeaders(), | 2769 | headers: getRequestHeaders(), |
| 2770 | signal: signal, | ||
| 2752 | body: JSON.stringify({ | 2771 | body: JSON.stringify({ |
| 2753 | model: extension_settings.sd.model, | 2772 | model: extension_settings.sd.model, |
| 2754 | payload: { | 2773 | payload: { |
| @@ -2783,12 +2802,14 @@ async function generateStabilityImage(prompt, negativePrompt) { | |||
| 2783 | * | 2802 | * |
| 2784 | * @param {string} prompt - The main instruction used to guide the image generation. | 2803 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2785 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2804 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2805 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2786 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2806 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2787 | */ | 2807 | */ |
| 2788 | async function generateHordeImage(prompt, negativePrompt) { | 2808 | async function generateHordeImage(prompt, negativePrompt, signal) { |
| 2789 | const result = await fetch('/api/horde/generate-image', { | 2809 | const result = await fetch('/api/horde/generate-image', { |
| 2790 | method: 'POST', | 2810 | method: 'POST', |
| 2791 | headers: getRequestHeaders(), | 2811 | headers: getRequestHeaders(), |
| 2812 | signal: signal, | ||
| 2792 | body: JSON.stringify({ | 2813 | body: JSON.stringify({ |
| 2793 | prompt: prompt, | 2814 | prompt: prompt, |
| 2794 | sampler: extension_settings.sd.sampler, | 2815 | sampler: extension_settings.sd.sampler, |
| @@ -2821,13 +2842,15 @@ async function generateHordeImage(prompt, negativePrompt) { | |||
| 2821 | * | 2842 | * |
| 2822 | * @param {string} prompt - The main instruction used to guide the image generation. | 2843 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2823 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2844 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2845 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2824 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2846 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2825 | */ | 2847 | */ |
| 2826 | async function generateAutoImage(prompt, negativePrompt) { | 2848 | async function generateAutoImage(prompt, negativePrompt, signal) { |
| 2827 | const isValidVae = extension_settings.sd.vae && !['N/A', placeholderVae].includes(extension_settings.sd.vae); | 2849 | const isValidVae = extension_settings.sd.vae && !['N/A', placeholderVae].includes(extension_settings.sd.vae); |
| 2828 | const result = await fetch('/api/sd/generate', { | 2850 | const result = await fetch('/api/sd/generate', { |
| 2829 | method: 'POST', | 2851 | method: 'POST', |
| 2830 | headers: getRequestHeaders(), | 2852 | headers: getRequestHeaders(), |
| 2853 | signal: signal, | ||
| 2831 | body: JSON.stringify({ | 2854 | body: JSON.stringify({ |
| 2832 | ...getSdRequestBody(), | 2855 | ...getSdRequestBody(), |
| 2833 | prompt: prompt, | 2856 | prompt: prompt, |
| @@ -2875,12 +2898,14 @@ async function generateAutoImage(prompt, negativePrompt) { | |||
| 2875 | * | 2898 | * |
| 2876 | * @param {string} prompt - The main instruction used to guide the image generation. | 2899 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2877 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2900 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2901 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2878 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2902 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2879 | */ | 2903 | */ |
| 2880 | async function generateDrawthingsImage(prompt, negativePrompt) { | 2904 | async function generateDrawthingsImage(prompt, negativePrompt, signal) { |
| 2881 | const result = await fetch('/api/sd/drawthings/generate', { | 2905 | const result = await fetch('/api/sd/drawthings/generate', { |
| 2882 | method: 'POST', | 2906 | method: 'POST', |
| 2883 | headers: getRequestHeaders(), | 2907 | headers: getRequestHeaders(), |
| 2908 | signal: signal, | ||
| 2884 | body: JSON.stringify({ | 2909 | body: JSON.stringify({ |
| 2885 | ...getSdRequestBody(), | 2910 | ...getSdRequestBody(), |
| 2886 | prompt: prompt, | 2911 | prompt: prompt, |
| @@ -2914,14 +2939,16 @@ async function generateDrawthingsImage(prompt, negativePrompt) { | |||
| 2914 | * | 2939 | * |
| 2915 | * @param {string} prompt - The main instruction used to guide the image generation. | 2940 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 2916 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 2941 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 2942 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 2917 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 2943 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 2918 | */ | 2944 | */ |
| 2919 | async function generateNovelImage(prompt, negativePrompt) { | 2945 | async function generateNovelImage(prompt, negativePrompt, signal) { |
| 2920 | const { steps, width, height, sm, sm_dyn } = getNovelParams(); | 2946 | const { steps, width, height, sm, sm_dyn } = getNovelParams(); |
| 2921 | 2947 | ||
| 2922 | const result = await fetch('/api/novelai/generate-image', { | 2948 | const result = await fetch('/api/novelai/generate-image', { |
| 2923 | method: 'POST', | 2949 | method: 'POST', |
| 2924 | headers: getRequestHeaders(), | 2950 | headers: getRequestHeaders(), |
| 2951 | signal: signal, | ||
| 2925 | body: JSON.stringify({ | 2952 | body: JSON.stringify({ |
| 2926 | prompt: prompt, | 2953 | prompt: prompt, |
| 2927 | model: extension_settings.sd.model, | 2954 | model: extension_settings.sd.model, |
| @@ -3010,7 +3037,13 @@ function getNovelParams() { | |||
| 3010 | return { steps, width, height, sm, sm_dyn }; | 3037 | return { steps, width, height, sm, sm_dyn }; |
| 3011 | } | 3038 | } |
| 3012 | 3039 | ||
| 3013 | async function generateOpenAiImage(prompt) { | 3040 | /** |
| 3041 | * Generates an image in OpenAI API using the provided prompt and configuration settings. | ||
| 3042 | * @param {string} prompt - The main instruction used to guide the image generation. | ||
| 3043 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 3044 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | ||
| 3045 | */ | ||
| 3046 | async function generateOpenAiImage(prompt, signal) { | ||
| 3014 | const dalle2PromptLimit = 1000; | 3047 | const dalle2PromptLimit = 1000; |
| 3015 | const dalle3PromptLimit = 4000; | 3048 | const dalle3PromptLimit = 4000; |
| 3016 | 3049 | ||
| @@ -3045,6 +3078,7 @@ async function generateOpenAiImage(prompt) { | |||
| 3045 | const result = await fetch('/api/openai/generate-image', { | 3078 | const result = await fetch('/api/openai/generate-image', { |
| 3046 | method: 'POST', | 3079 | method: 'POST', |
| 3047 | headers: getRequestHeaders(), | 3080 | headers: getRequestHeaders(), |
| 3081 | signal: signal, | ||
| 3048 | body: JSON.stringify({ | 3082 | body: JSON.stringify({ |
| 3049 | prompt: prompt, | 3083 | prompt: prompt, |
| 3050 | model: extension_settings.sd.model, | 3084 | model: extension_settings.sd.model, |
| @@ -3070,9 +3104,10 @@ async function generateOpenAiImage(prompt) { | |||
| 3070 | * | 3104 | * |
| 3071 | * @param {string} prompt - The main instruction used to guide the image generation. | 3105 | * @param {string} prompt - The main instruction used to guide the image generation. |
| 3072 | * @param {string} negativePrompt - The instruction used to restrict the image generation. | 3106 | * @param {string} negativePrompt - The instruction used to restrict the image generation. |
| 3107 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 3073 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | 3108 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. |
| 3074 | */ | 3109 | */ |
| 3075 | async function generateComfyImage(prompt, negativePrompt) { | 3110 | async function generateComfyImage(prompt, negativePrompt, signal) { |
| 3076 | const placeholders = [ | 3111 | const placeholders = [ |
| 3077 | 'model', | 3112 | 'model', |
| 3078 | 'vae', | 3113 | 'vae', |
| @@ -3133,6 +3168,7 @@ async function generateComfyImage(prompt, negativePrompt) { | |||
| 3133 | const promptResult = await fetch('/api/sd/comfy/generate', { | 3168 | const promptResult = await fetch('/api/sd/comfy/generate', { |
| 3134 | method: 'POST', | 3169 | method: 'POST', |
| 3135 | headers: getRequestHeaders(), | 3170 | headers: getRequestHeaders(), |
| 3171 | signal: signal, | ||
| 3136 | body: JSON.stringify({ | 3172 | body: JSON.stringify({ |
| 3137 | url: extension_settings.sd.comfy_url, | 3173 | url: extension_settings.sd.comfy_url, |
| 3138 | prompt: `{ | 3174 | prompt: `{ |
| @@ -3245,7 +3281,7 @@ async function onComfyNewWorkflowClick() { | |||
| 3245 | if (!name) { | 3281 | if (!name) { |
| 3246 | return; | 3282 | return; |
| 3247 | } | 3283 | } |
| 3248 | if (!name.toLowerCase().endsWith('.json')) { | 3284 | if (!String(name).toLowerCase().endsWith('.json')) { |
| 3249 | name += '.json'; | 3285 | name += '.json'; |
| 3250 | } | 3286 | } |
| 3251 | extension_settings.sd.comfy_workflow = name; | 3287 | extension_settings.sd.comfy_workflow = name; |
| @@ -3448,8 +3484,10 @@ async function sdMessageButton(e) { | |||
| 3448 | const messageText = message?.mes; | 3484 | const messageText = message?.mes; |
| 3449 | const hasSavedImage = message?.extra?.image && message?.extra?.title; | 3485 | const hasSavedImage = message?.extra?.image && message?.extra?.title; |
| 3450 | const hasSavedNegative = message?.extra?.negative; | 3486 | const hasSavedNegative = message?.extra?.negative; |
| 3487 | const abortController = new AbortController(); | ||
| 3451 | 3488 | ||
| 3452 | if ($icon.hasClass(busyClass)) { | 3489 | if ($icon.hasClass(busyClass)) { |
| 3490 | abortController.abort(); | ||
| 3453 | console.log('Previous image is still being generated...'); | 3491 | console.log('Previous image is still being generated...'); |
| 3454 | return; | 3492 | return; |
| 3455 | } | 3493 | } |
| @@ -3466,7 +3504,7 @@ async function sdMessageButton(e) { | |||
| 3466 | const generationType = message?.extra?.generationType ?? generationMode.FREE; | 3504 | const generationType = message?.extra?.generationType ?? generationMode.FREE; |
| 3467 | console.log('Regenerating an image, using existing prompt:', prompt); | 3505 | console.log('Regenerating an image, using existing prompt:', prompt); |
| 3468 | dimensions = setTypeSpecificDimensions(generationType); | 3506 | dimensions = setTypeSpecificDimensions(generationType); |
| 3469 | await sendGenerationRequest(generationType, prompt, negative, characterFileName, saveGeneratedImage, initiators.action); | 3507 | await sendGenerationRequest(generationType, prompt, negative, characterFileName, saveGeneratedImage, initiators.action, abortController.signal); |
| 3470 | } | 3508 | } |
| 3471 | else { | 3509 | else { |
| 3472 | console.log('doing /sd raw last'); | 3510 | console.log('doing /sd raw last'); |
| @@ -339,7 +339,18 @@ router.post('/generate-image', jsonParser, async (request, response) => { | |||
| 339 | return response.sendStatus(400); | 339 | return response.sendStatus(400); |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | console.log('Horde image generation request:', generation); | ||
| 343 | |||
| 344 | const controller = new AbortController(); | ||
| 345 | request.socket.removeAllListeners('close'); | ||
| 346 | request.socket.on('close', function () { | ||
| 347 | console.log('Horde image generation request aborted.'); | ||
| 348 | controller.abort(); | ||
| 349 | if (generation.id) ai_horde.deleteImageGenerationRequest(generation.id); | ||
| 350 | }); | ||
| 351 | |||
| 342 | for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { | 352 | for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { |
| 353 | controller.signal.throwIfAborted(); | ||
| 343 | await delay(CHECK_INTERVAL); | 354 | await delay(CHECK_INTERVAL); |
| 344 | const check = await ai_horde.getImageGenerationCheck(generation.id); | 355 | const check = await ai_horde.getImageGenerationCheck(generation.id); |
| 345 | console.log(check); | 356 | console.log(check); |