Merge pull request #2640 from edk208/release Adding Block Entropy API endpoints for chat, image, and video generation
Signed| @@ -0,0 +1,3 @@ | ||
| 1 | +<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 236.38 282.41"> | |
| 2 | + <path d="M126.55,0v54.44l-79.87,33.76v93.95l27.53-12.94,43.08,31.09.04-.05v.09l55.21-31.44.13-.08v-80.06l-55.34,24.92v80.2l-42.55-30.7h-.02s0-81.16,0-81.16l57.02-24.11V9.23l93.54,56.12v22.51l-24.34,11.53,1.84,90.56-88.45,51.47-.13.08v34.46L5.23,198.97v-65.56H0v66.92c0,.85.41,1.64,1.11,2.14l113.13,79.91v.05l.04-.02h0s0,0,0,0l121.97-73.54.13-.08v-126.13l-5.84,2.76v-22.94h-.3l.11-.18L126.55,0Z" /> | |
| 3 | +</svg> | |
| @@ -2427,6 +2427,7 @@ | ||
| 2427 | 2427 | <optgroup> |
| 2428 | 2428 | <option value="01ai">01.AI (Yi)</option> |
| 2429 | 2429 | <option value="ai21">AI21</option> |
| 2430 | + <option value="blockentropy">Block Entropy</option> | |
| 2430 | 2431 | <option value="claude">Claude</option> |
| 2431 | 2432 | <option value="cohere">Cohere</option> |
| 2432 | 2433 | <option value="groq">Groq</option> |
| @@ -2952,6 +2953,20 @@ | ||
| 2952 | 2953 | </select> |
| 2953 | 2954 | </div> |
| 2954 | 2955 | </form> |
| 2956 | + <form id="blockentropy_form" data-source="blockentropy"> | |
| 2957 | + <h4 data-i18n="Block Entropy API Key">Block Entropy API Key</h4> | |
| 2958 | + <div class="flex-container"> | |
| 2959 | + <input id="api_key_blockentropy" name="api_key_blockentropy" class="text_pole flex1" maxlength="500" value="" type="text" autocomplete="off"> | |
| 2960 | + <div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_blockentropy"></div> | |
| 2961 | + </div> | |
| 2962 | + <div data-for="api_key_blockentropy" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page."> | |
| 2963 | + For privacy reasons, your API key will be hidden after you reload the page. | |
| 2964 | + </div> | |
| 2965 | + <h4 data-i18n="Select a Model">Select a Model</h4> | |
| 2966 | + <div class="flex-container"> | |
| 2967 | + <select id="model_blockentropy_select" class="text_pole"></select> | |
| 2968 | + </div> | |
| 2969 | + </form> | |
| 2955 | 2970 | <form id="custom_form" data-source="custom"> |
| 2956 | 2971 | <h4 data-i18n="Custom Endpoint (Base URL)">Custom Endpoint (Base URL)</h4> |
| 2957 | 2972 | <div class="flex-container"> |
| @@ -380,6 +380,7 @@ function RA_autoconnect(PrevApi) { | ||
| 380 | 380 | || (secret_state[SECRET_KEYS.PERPLEXITY] && oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) |
| 381 | 381 | || (secret_state[SECRET_KEYS.GROQ] && oai_settings.chat_completion_source == chat_completion_sources.GROQ) |
| 382 | 382 | || (secret_state[SECRET_KEYS.ZEROONEAI] && oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI) |
| 383 | + || (secret_state[SECRET_KEYS.BLOCKENTROPY] && oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) | |
| 383 | 384 | || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) |
| 384 | 385 | ) { |
| 385 | 386 | $('#api_button_openai').trigger('click'); |
| @@ -51,6 +51,7 @@ const sources = { | ||
| 51 | 51 | drawthings: 'drawthings', |
| 52 | 52 | pollinations: 'pollinations', |
| 53 | 53 | stability: 'stability', |
| 54 | + blockentropy: 'blockentropy', | |
| 54 | 55 | }; |
| 55 | 56 | |
| 56 | 57 | const initiators = { |
| @@ -1222,7 +1223,7 @@ async function onModelChange() { | ||
| 1222 | 1223 | extension_settings.sd.model = $('#sd_model').find(':selected').val(); |
| 1223 | 1224 | saveSettingsDebounced(); |
| 1224 | 1225 | |
| 1225 | 1226 | const cloudSources = [sources.horde, sources.novel, sources.openai, sources.togetherai, sources.pollinations, sources.stability, sources.blockentropy]; |
| 1226 | 1227 | |
| 1227 | 1228 | if (cloudSources.includes(extension_settings.sd.source)) { |
| 1228 | 1229 | return; |
| @@ -1434,6 +1435,9 @@ async function loadSamplers() { | ||
| 1434 | 1435 | case sources.stability: |
| 1435 | 1436 | samplers = ['N/A']; |
| 1436 | 1437 | break; |
| 1438 | + case sources.blockentropy: | |
| 1439 | + samplers = ['N/A']; | |
| 1440 | + break; | |
| 1437 | 1441 | } |
| 1438 | 1442 | |
| 1439 | 1443 | for (const sampler of samplers) { |
| @@ -1620,6 +1624,9 @@ async function loadModels() { | ||
| 1620 | 1624 | case sources.stability: |
| 1621 | 1625 | models = await loadStabilityModels(); |
| 1622 | 1626 | break; |
| 1627 | + case sources.blockentropy: | |
| 1628 | + models = await loadBlockEntropyModels(); | |
| 1629 | + break; | |
| 1623 | 1630 | } |
| 1624 | 1631 | |
| 1625 | 1632 | for (const model of models) { |
| @@ -1714,6 +1721,26 @@ async function loadTogetherAIModels() { | ||
| 1714 | 1721 | return []; |
| 1715 | 1722 | } |
| 1716 | 1723 | |
| 1724 | +async function loadBlockEntropyModels() { | |
| 1725 | + if (!secret_state[SECRET_KEYS.BLOCKENTROPY]) { | |
| 1726 | + console.debug('Block Entropy API key is not set.'); | |
| 1727 | + return []; | |
| 1728 | + } | |
| 1729 | + | |
| 1730 | + const result = await fetch('/api/sd/blockentropy/models', { | |
| 1731 | + method: 'POST', | |
| 1732 | + headers: getRequestHeaders(), | |
| 1733 | + }); | |
| 1734 | + console.log(result); | |
| 1735 | + if (result.ok) { | |
| 1736 | + const data = await result.json(); | |
| 1737 | + console.log(data); | |
| 1738 | + return data; | |
| 1739 | + } | |
| 1740 | + | |
| 1741 | + return []; | |
| 1742 | +} | |
| 1743 | + | |
| 1717 | 1744 | async function loadHordeModels() { |
| 1718 | 1745 | const result = await fetch('/api/horde/sd-models', { |
| 1719 | 1746 | method: 'POST', |
| @@ -1980,6 +2007,9 @@ async function loadSchedulers() { | ||
| 1980 | 2007 | case sources.stability: |
| 1981 | 2008 | schedulers = ['N/A']; |
| 1982 | 2009 | break; |
| 2010 | + case sources.blockentropy: | |
| 2011 | + schedulers = ['N/A']; | |
| 2012 | + break; | |
| 1983 | 2013 | } |
| 1984 | 2014 | |
| 1985 | 2015 | for (const scheduler of schedulers) { |
| @@ -2056,6 +2086,9 @@ async function loadVaes() { | ||
| 2056 | 2086 | case sources.stability: |
| 2057 | 2087 | vaes = ['N/A']; |
| 2058 | 2088 | break; |
| 2089 | + case sources.blockentropy: | |
| 2090 | + vaes = ['N/A']; | |
| 2091 | + break; | |
| 2059 | 2092 | } |
| 2060 | 2093 | |
| 2061 | 2094 | for (const vae of vaes) { |
| @@ -2584,6 +2617,9 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP | ||
| 2584 | 2617 | case sources.stability: |
| 2585 | 2618 | result = await generateStabilityImage(prefixedPrompt, negativePrompt, signal); |
| 2586 | 2619 | break; |
| 2620 | + case sources.blockentropy: | |
| 2621 | + result = await generateBlockEntropyImage(prefixedPrompt, negativePrompt, signal); | |
| 2622 | + break; | |
| 2587 | 2623 | } |
| 2588 | 2624 | |
| 2589 | 2625 | if (!result.data) { |
| @@ -2639,6 +2675,40 @@ async function generateTogetherAIImage(prompt, negativePrompt, signal) { | ||
| 2639 | 2675 | } |
| 2640 | 2676 | } |
| 2641 | 2677 | |
| 2678 | +async function generateBlockEntropyImage(prompt, negativePrompt, signal) { | |
| 2679 | + const result = await fetch('/api/sd/blockentropy/generate', { | |
| 2680 | + method: 'POST', | |
| 2681 | + headers: getRequestHeaders(), | |
| 2682 | + signal: signal, | |
| 2683 | + body: JSON.stringify({ | |
| 2684 | + prompt: prompt, | |
| 2685 | + negative_prompt: negativePrompt, | |
| 2686 | + model: extension_settings.sd.model, | |
| 2687 | + steps: extension_settings.sd.steps, | |
| 2688 | + width: extension_settings.sd.width, | |
| 2689 | + height: extension_settings.sd.height, | |
| 2690 | + seed: extension_settings.sd.seed >= 0 ? extension_settings.sd.seed : undefined, | |
| 2691 | + }), | |
| 2692 | + }); | |
| 2693 | + | |
| 2694 | + if (result.ok) { | |
| 2695 | + const data = await result.json(); | |
| 2696 | + | |
| 2697 | + // Default format is 'jpg' | |
| 2698 | + let format = 'jpg'; | |
| 2699 | + | |
| 2700 | + // Check if a format is specified in the result | |
| 2701 | + if (data.format) { | |
| 2702 | + format = data.format.toLowerCase(); | |
| 2703 | + } | |
| 2704 | + | |
| 2705 | + return { format: format, data: data.images[0] }; | |
| 2706 | + } else { | |
| 2707 | + const text = await result.text(); | |
| 2708 | + throw new Error(text); | |
| 2709 | + } | |
| 2710 | +} | |
| 2711 | + | |
| 2642 | 2712 | /** |
| 2643 | 2713 | * Generates an image using the Pollinations API. |
| 2644 | 2714 | * @param {string} prompt - The main instruction used to guide the image generation. |
| @@ -3459,6 +3529,8 @@ function isValidState() { | ||
| 3459 | 3529 | return true; |
| 3460 | 3530 | case sources.stability: |
| 3461 | 3531 | return secret_state[SECRET_KEYS.STABILITY]; |
| 3532 | + case sources.blockentropy: | |
| 3533 | + return secret_state[SECRET_KEYS.BLOCKENTROPY]; | |
| 3462 | 3534 | } |
| 3463 | 3535 | } |
| 3464 | 3536 | |
| @@ -37,6 +37,7 @@ | ||
| 37 | 37 | </label> |
| 38 | 38 | <label for="sd_source" data-i18n="Source">Source</label> |
| 39 | 39 | <select id="sd_source"> |
| 40 | + <option value="blockentropy">Block Entropy</option> | |
| 40 | 41 | <option value="comfy">ComfyUI</option> |
| 41 | 42 | <option value="drawthings">DrawThings HTTP API</option> |
| 42 | 43 | <option value="extras">Extras API (local / remote)</option> |
| @@ -378,7 +379,7 @@ | ||
| 378 | 379 | </label> |
| 379 | 380 | </div> |
| 380 | 381 | |
| 381 | 382 | <div data-sd-source="novel,togetherai,pollinations,comfy,drawthings,vlad,auto,horde,extras,stability,blockentropy" class="marginTop5"> |
| 382 | 383 | <label for="sd_seed"> |
| 383 | 384 | <span data-i18n="Seed">Seed</span> |
| 384 | 385 | <small data-i18n="(-1 for random)">(-1 for random)</small> |
| @@ -120,6 +120,7 @@ const default_bias_presets = { | ||
| 120 | 120 | const max_2k = 2047; |
| 121 | 121 | const max_4k = 4095; |
| 122 | 122 | const max_8k = 8191; |
| 123 | +const max_12k = 12287; | |
| 123 | 124 | const max_16k = 16383; |
| 124 | 125 | const max_32k = 32767; |
| 125 | 126 | const max_64k = 65535; |
| @@ -186,6 +187,7 @@ export const chat_completion_sources = { | ||
| 186 | 187 | PERPLEXITY: 'perplexity', |
| 187 | 188 | GROQ: 'groq', |
| 188 | 189 | ZEROONEAI: '01ai', |
| 190 | + BLOCKENTROPY: 'blockentropy', | |
| 189 | 191 | }; |
| 190 | 192 | |
| 191 | 193 | const character_names_behavior = { |
| @@ -268,6 +270,7 @@ const default_settings = { | ||
| 268 | 270 | perplexity_model: 'llama-3.1-70b-instruct', |
| 269 | 271 | groq_model: 'llama-3.1-70b-versatile', |
| 270 | 272 | zerooneai_model: 'yi-large', |
| 273 | + blockentropy_model: 'be-70b-base-llama3.1', | |
| 271 | 274 | custom_model: '', |
| 272 | 275 | custom_url: '', |
| 273 | 276 | custom_include_body: '', |
| @@ -348,6 +351,7 @@ const oai_settings = { | ||
| 348 | 351 | perplexity_model: 'llama-3.1-70b-instruct', |
| 349 | 352 | groq_model: 'llama-3.1-70b-versatile', |
| 350 | 353 | zerooneai_model: 'yi-large', |
| 354 | + blockentropy_model: 'be-70b-base-llama3.1', | |
| 351 | 355 | custom_model: '', |
| 352 | 356 | custom_url: '', |
| 353 | 357 | custom_include_body: '', |
| @@ -1542,6 +1546,8 @@ function getChatCompletionModel() { | ||
| 1542 | 1546 | return oai_settings.groq_model; |
| 1543 | 1547 | case chat_completion_sources.ZEROONEAI: |
| 1544 | 1548 | return oai_settings.zerooneai_model; |
| 1549 | + case chat_completion_sources.BLOCKENTROPY: | |
| 1550 | + return oai_settings.blockentropy_model; | |
| 1545 | 1551 | default: |
| 1546 | 1552 | throw new Error(`Unknown chat completion source: ${oai_settings.chat_completion_source}`); |
| 1547 | 1553 | } |
| @@ -1655,6 +1661,23 @@ function saveModelList(data) { | ||
| 1655 | 1661 | |
| 1656 | 1662 | $('#model_01ai_select').val(oai_settings.zerooneai_model).trigger('change'); |
| 1657 | 1663 | } |
| 1664 | + | |
| 1665 | + if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { | |
| 1666 | + $('#model_blockentropy_select').empty(); | |
| 1667 | + model_list.forEach((model) => { | |
| 1668 | + $('#model_blockentropy_select').append( | |
| 1669 | + $('<option>', { | |
| 1670 | + value: model.id, | |
| 1671 | + text: model.id, | |
| 1672 | + })); | |
| 1673 | + }); | |
| 1674 | + | |
| 1675 | + if (!oai_settings.blockentropy_model && model_list.length > 0) { | |
| 1676 | + oai_settings.blockentropy_model = model_list[0].id; | |
| 1677 | + } | |
| 1678 | + | |
| 1679 | + $('#model_blockentropy_select').val(oai_settings.blockentropy_model).trigger('change'); | |
| 1680 | + } | |
| 1658 | 1681 | } |
| 1659 | 1682 | |
| 1660 | 1683 | function appendOpenRouterOptions(model_list, groupModels = false, sort = false) { |
| @@ -3015,6 +3038,7 @@ function loadOpenAISettings(data, settings) { | ||
| 3015 | 3038 | oai_settings.cohere_model = settings.cohere_model ?? default_settings.cohere_model; |
| 3016 | 3039 | oai_settings.perplexity_model = settings.perplexity_model ?? default_settings.perplexity_model; |
| 3017 | 3040 | oai_settings.groq_model = settings.groq_model ?? default_settings.groq_model; |
| 3041 | + oai_settings.blockentropy_model = settings.blockentropy_model ?? default_settings.blockentropy_model; | |
| 3018 | 3042 | oai_settings.zerooneai_model = settings.zerooneai_model ?? default_settings.zerooneai_model; |
| 3019 | 3043 | oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model; |
| 3020 | 3044 | oai_settings.custom_url = settings.custom_url ?? default_settings.custom_url; |
| @@ -3094,6 +3118,7 @@ function loadOpenAISettings(data, settings) { | ||
| 3094 | 3118 | $('#model_groq_select').val(oai_settings.groq_model); |
| 3095 | 3119 | $(`#model_groq_select option[value="${oai_settings.groq_model}"`).attr('selected', true); |
| 3096 | 3120 | $('#model_01ai_select').val(oai_settings.zerooneai_model); |
| 3121 | + $('#model_blockentropy_select').val(oai_settings.blockentropy_model); | |
| 3097 | 3122 | $('#custom_model_id').val(oai_settings.custom_model); |
| 3098 | 3123 | $('#custom_api_url_text').val(oai_settings.custom_url); |
| 3099 | 3124 | $('#openai_max_context').val(oai_settings.openai_max_context); |
| @@ -3355,6 +3380,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | ||
| 3355 | 3380 | perplexity_model: settings.perplexity_model, |
| 3356 | 3381 | groq_model: settings.groq_model, |
| 3357 | 3382 | zerooneai_model: settings.zerooneai_model, |
| 3383 | + blockentropy_model: settings.blockentropy_model, | |
| 3358 | 3384 | custom_model: settings.custom_model, |
| 3359 | 3385 | custom_url: settings.custom_url, |
| 3360 | 3386 | custom_include_body: settings.custom_include_body, |
| @@ -3795,6 +3821,7 @@ function onSettingsPresetChange() { | ||
| 3795 | 3821 | perplexity_model: ['#model_perplexity_select', 'perplexity_model', false], |
| 3796 | 3822 | groq_model: ['#model_groq_select', 'groq_model', false], |
| 3797 | 3823 | zerooneai_model: ['#model_01ai_select', 'zerooneai_model', false], |
| 3824 | + blockentropy_model: ['#model_blockentropy_select', 'blockentropy_model', false], | |
| 3798 | 3825 | custom_model: ['#custom_model_id', 'custom_model', false], |
| 3799 | 3826 | custom_url: ['#custom_api_url_text', 'custom_url', false], |
| 3800 | 3827 | custom_include_body: ['#custom_include_body', 'custom_include_body', false], |
| @@ -4042,6 +4069,12 @@ async function onModelChange() { | ||
| 4042 | 4069 | oai_settings.zerooneai_model = value; |
| 4043 | 4070 | } |
| 4044 | 4071 | |
| 4072 | + if (value && $(this).is('#model_blockentropy_select')) { | |
| 4073 | + console.log('Block Entropy model changed to', value); | |
| 4074 | + oai_settings.blockentropy_model = value; | |
| 4075 | + $('#blockentropy_model_id').val(value).trigger('input'); | |
| 4076 | + } | |
| 4077 | + | |
| 4045 | 4078 | if (value && $(this).is('#model_custom_select')) { |
| 4046 | 4079 | console.log('Custom model changed to', value); |
| 4047 | 4080 | oai_settings.custom_model = value; |
| @@ -4330,6 +4363,29 @@ async function onModelChange() { | ||
| 4330 | 4363 | oai_settings.temp_openai = Math.min(oai_max_temp, oai_settings.temp_openai); |
| 4331 | 4364 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4332 | 4365 | } |
| 4366 | + if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) { | |
| 4367 | + if (oai_settings.max_context_unlocked) { | |
| 4368 | + $('#openai_max_context').attr('max', unlocked_max); | |
| 4369 | + } | |
| 4370 | + else if (oai_settings.blockentropy_model.includes('llama3.1')) { | |
| 4371 | + $('#openai_max_context').attr('max', max_16k); | |
| 4372 | + } | |
| 4373 | + else if (oai_settings.blockentropy_model.includes('72b')) { | |
| 4374 | + $('#openai_max_context').attr('max', max_16k); | |
| 4375 | + } | |
| 4376 | + else if (oai_settings.blockentropy_model.includes('120b')) { | |
| 4377 | + $('#openai_max_context').attr('max', max_12k); | |
| 4378 | + } | |
| 4379 | + else { | |
| 4380 | + $('#openai_max_context').attr('max', max_8k); | |
| 4381 | + } | |
| 4382 | + | |
| 4383 | + oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max'))); | |
| 4384 | + $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); | |
| 4385 | + | |
| 4386 | + oai_settings.temp_openai = Math.min(oai_max_temp, oai_settings.temp_openai); | |
| 4387 | + $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | |
| 4388 | + } | |
| 4333 | 4389 | |
| 4334 | 4390 | $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); |
| 4335 | 4391 | |
| @@ -4537,6 +4593,18 @@ async function onConnectButtonClick(e) { | ||
| 4537 | 4593 | return; |
| 4538 | 4594 | } |
| 4539 | 4595 | } |
| 4596 | + if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { | |
| 4597 | + const api_key_blockentropy = String($('#api_key_blockentropy').val()).trim(); | |
| 4598 | + | |
| 4599 | + if (api_key_blockentropy.length) { | |
| 4600 | + await writeSecret(SECRET_KEYS.BLOCKENTROPY, api_key_blockentropy); | |
| 4601 | + } | |
| 4602 | + | |
| 4603 | + if (!secret_state[SECRET_KEYS.BLOCKENTROPY]) { | |
| 4604 | + console.log('No secret key saved for Block Entropy'); | |
| 4605 | + return; | |
| 4606 | + } | |
| 4607 | + } | |
| 4540 | 4608 | |
| 4541 | 4609 | startStatusLoading(); |
| 4542 | 4610 | saveSettingsDebounced(); |
| @@ -4588,6 +4656,9 @@ function toggleChatCompletionForms() { | ||
| 4588 | 4656 | else if (oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) { |
| 4589 | 4657 | $('#model_custom_select').trigger('change'); |
| 4590 | 4658 | } |
| 4659 | + else if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { | |
| 4660 | + $('#model_blockentropy_select').trigger('change'); | |
| 4661 | + } | |
| 4591 | 4662 | $('[data-source]').each(function () { |
| 4592 | 4663 | const validSources = $(this).data('source').split(','); |
| 4593 | 4664 | $(this).toggle(validSources.includes(oai_settings.chat_completion_source)); |
| @@ -5317,6 +5388,7 @@ $(document).ready(async function () { | ||
| 5317 | 5388 | $('#model_perplexity_select').on('change', onModelChange); |
| 5318 | 5389 | $('#model_groq_select').on('change', onModelChange); |
| 5319 | 5390 | $('#model_01ai_select').on('change', onModelChange); |
| 5391 | + $('#model_blockentropy_select').on('change', onModelChange); | |
| 5320 | 5392 | $('#model_custom_select').on('change', onModelChange); |
| 5321 | 5393 | $('#settings_preset_openai').on('change', onSettingsPresetChange); |
| 5322 | 5394 | $('#new_oai_preset').on('click', onNewPresetClick); |
| @@ -32,6 +32,7 @@ export const SECRET_KEYS = { | ||
| 32 | 32 | ZEROONEAI: 'api_key_01ai', |
| 33 | 33 | HUGGINGFACE: 'api_key_huggingface', |
| 34 | 34 | STABILITY: 'api_key_stability', |
| 35 | + BLOCKENTROPY: 'api_key_blockentropy', | |
| 35 | 36 | }; |
| 36 | 37 | |
| 37 | 38 | const INPUT_MAP = { |
| @@ -63,6 +64,7 @@ const INPUT_MAP = { | ||
| 63 | 64 | [SECRET_KEYS.FEATHERLESS]: '#api_key_featherless', |
| 64 | 65 | [SECRET_KEYS.ZEROONEAI]: '#api_key_01ai', |
| 65 | 66 | [SECRET_KEYS.HUGGINGFACE]: '#api_key_huggingface', |
| 67 | + [SECRET_KEYS.BLOCKENTROPY]: '#api_key_blockentropy', | |
| 66 | 68 | }; |
| 67 | 69 | |
| 68 | 70 | async function clearSecret() { |
| @@ -3249,6 +3249,7 @@ function getModelOptions() { | ||
| 3249 | 3249 | { id: 'model_perplexity_select', api: 'openai', type: chat_completion_sources.PERPLEXITY }, |
| 3250 | 3250 | { id: 'model_groq_select', api: 'openai', type: chat_completion_sources.GROQ }, |
| 3251 | 3251 | { id: 'model_01ai_select', api: 'openai', type: chat_completion_sources.ZEROONEAI }, |
| 3252 | + { id: 'model_blockentropy_select', api: 'openai', type: chat_completion_sources.BLOCKENTROPY }, | |
| 3252 | 3253 | { id: 'model_novel_select', api: 'novel', type: null }, |
| 3253 | 3254 | { id: 'horde_model', api: 'koboldhorde', type: null }, |
| 3254 | 3255 | ]; |
| @@ -549,6 +549,15 @@ export function getTokenizerModel() { | ||
| 549 | 549 | return yiTokenizer; |
| 550 | 550 | } |
| 551 | 551 | |
| 552 | + if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) { | |
| 553 | + if (oai_settings.blockentropy_model.includes('llama3')) { | |
| 554 | + return llama3Tokenizer; | |
| 555 | + } | |
| 556 | + if (oai_settings.blockentropy_model.includes('miqu') || oai_settings.blockentropy_model.includes('mixtral')) { | |
| 557 | + return mistralTokenizer; | |
| 558 | + } | |
| 559 | + } | |
| 560 | + | |
| 552 | 561 | // Default to Turbo 3.5 |
| 553 | 562 | return turboTokenizer; |
| 554 | 563 | } |
| @@ -195,6 +195,7 @@ const CHAT_COMPLETION_SOURCES = { | ||
| 195 | 195 | PERPLEXITY: 'perplexity', |
| 196 | 196 | GROQ: 'groq', |
| 197 | 197 | ZEROONEAI: '01ai', |
| 198 | + BLOCKENTROPY: 'blockentropy', | |
| 198 | 199 | }; |
| 199 | 200 | |
| 200 | 201 | /** |
| @@ -18,6 +18,7 @@ const API_PERPLEXITY = 'https://api.perplexity.ai'; | ||
| 18 | 18 | const API_GROQ = 'https://api.groq.com/openai/v1'; |
| 19 | 19 | const API_MAKERSUITE = 'https://generativelanguage.googleapis.com'; |
| 20 | 20 | const API_01AI = 'https://api.01.ai/v1'; |
| 21 | +const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1'; | |
| 21 | 22 | |
| 22 | 23 | /** |
| 23 | 24 | * Applies a post-processing step to the generated messages. |
| @@ -675,6 +676,10 @@ router.post('/status', jsonParser, async function (request, response_getstatus_o | ||
| 675 | 676 | api_url = API_01AI; |
| 676 | 677 | api_key_openai = readSecret(request.user.directories, SECRET_KEYS.ZEROONEAI); |
| 677 | 678 | headers = {}; |
| 679 | + } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.BLOCKENTROPY) { | |
| 680 | + api_url = API_BLOCKENTROPY; | |
| 681 | + api_key_openai = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 682 | + headers = {}; | |
| 678 | 683 | } else { |
| 679 | 684 | console.log('This chat completion source is not supported yet.'); |
| 680 | 685 | return response_getstatus_openai.status(400).send({ error: true }); |
| @@ -941,6 +946,11 @@ router.post('/generate', jsonParser, function (request, response) { | ||
| 941 | 946 | apiKey = readSecret(request.user.directories, SECRET_KEYS.ZEROONEAI); |
| 942 | 947 | headers = {}; |
| 943 | 948 | bodyParams = {}; |
| 949 | + } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.BLOCKENTROPY) { | |
| 950 | + apiUrl = API_BLOCKENTROPY; | |
| 951 | + apiKey = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 952 | + headers = {}; | |
| 953 | + bodyParams = {}; | |
| 944 | 954 | } else { |
| 945 | 955 | console.log('This chat completion source is not supported yet.'); |
| 946 | 956 | return response.status(400).send({ error: true }); |
| @@ -44,6 +44,7 @@ const SECRET_KEYS = { | ||
| 44 | 44 | ZEROONEAI: 'api_key_01ai', |
| 45 | 45 | HUGGINGFACE: 'api_key_huggingface', |
| 46 | 46 | STABILITY: 'api_key_stability', |
| 47 | + BLOCKENTROPY: 'api_key_blockentropy', | |
| 47 | 48 | }; |
| 48 | 49 | |
| 49 | 50 | // These are the keys that are safe to expose, even if allowKeysExposure is false |
| @@ -908,10 +908,94 @@ stability.post('/generate', jsonParser, async (request, response) => { | ||
| 908 | 908 | } |
| 909 | 909 | }); |
| 910 | 910 | |
| 911 | +const blockentropy = express.Router(); | |
| 912 | + | |
| 913 | +blockentropy.post('/models', jsonParser, async (request, response) => { | |
| 914 | + try { | |
| 915 | + const key = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 916 | + | |
| 917 | + if (!key) { | |
| 918 | + console.log('Block Entropy key not found.'); | |
| 919 | + return response.sendStatus(400); | |
| 920 | + } | |
| 921 | + | |
| 922 | + const modelsResponse = await fetch('https://api.blockentropy.ai/sdapi/v1/sd-models', { | |
| 923 | + method: 'GET', | |
| 924 | + headers: { | |
| 925 | + 'Authorization': `Bearer ${key}`, | |
| 926 | + }, | |
| 927 | + }); | |
| 928 | + | |
| 929 | + if (!modelsResponse.ok) { | |
| 930 | + console.log('Block Entropy returned an error.'); | |
| 931 | + return response.sendStatus(500); | |
| 932 | + } | |
| 933 | + | |
| 934 | + const data = await modelsResponse.json(); | |
| 935 | + | |
| 936 | + if (!Array.isArray(data)) { | |
| 937 | + console.log('Block Entropy returned invalid data.'); | |
| 938 | + return response.sendStatus(500); | |
| 939 | + } | |
| 940 | + const models = data.map(x => ({ value: x.name, text: x.name })); | |
| 941 | + return response.send(models); | |
| 942 | + | |
| 943 | + } catch (error) { | |
| 944 | + console.log(error); | |
| 945 | + return response.sendStatus(500); | |
| 946 | + } | |
| 947 | +}); | |
| 948 | + | |
| 949 | +blockentropy.post('/generate', jsonParser, async (request, response) => { | |
| 950 | + try { | |
| 951 | + const key = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); | |
| 952 | + | |
| 953 | + if (!key) { | |
| 954 | + console.log('Block Entropy key not found.'); | |
| 955 | + return response.sendStatus(400); | |
| 956 | + } | |
| 957 | + | |
| 958 | + console.log('Block Entropy request:', request.body); | |
| 959 | + | |
| 960 | + const result = await fetch('https://api.blockentropy.ai/sdapi/v1/txt2img', { | |
| 961 | + method: 'POST', | |
| 962 | + body: JSON.stringify({ | |
| 963 | + prompt: request.body.prompt, | |
| 964 | + negative_prompt: request.body.negative_prompt, | |
| 965 | + model: request.body.model, | |
| 966 | + steps: request.body.steps, | |
| 967 | + width: request.body.width, | |
| 968 | + height: request.body.height, | |
| 969 | + // Random seed if negative. | |
| 970 | + seed: request.body.seed >= 0 ? request.body.seed : Math.floor(Math.random() * 10_000_000), | |
| 971 | + }), | |
| 972 | + headers: { | |
| 973 | + 'Content-Type': 'application/json', | |
| 974 | + 'Authorization': `Bearer ${key}`, | |
| 975 | + }, | |
| 976 | + }); | |
| 977 | + | |
| 978 | + if (!result.ok) { | |
| 979 | + console.log('Block Entropy returned an error.'); | |
| 980 | + return response.sendStatus(500); | |
| 981 | + } | |
| 982 | + | |
| 983 | + const data = await result.json(); | |
| 984 | + console.log('Block Entropy response:', data); | |
| 985 | + | |
| 986 | + return response.send(data); | |
| 987 | + } catch (error) { | |
| 988 | + console.log(error); | |
| 989 | + return response.sendStatus(500); | |
| 990 | + } | |
| 991 | +}); | |
| 992 | + | |
| 993 | + | |
| 911 | 994 | router.use('/comfy', comfy); |
| 912 | 995 | router.use('/together', together); |
| 913 | 996 | router.use('/drawthings', drawthings); |
| 914 | 997 | router.use('/pollinations', pollinations); |
| 915 | 998 | router.use('/stability', stability); |
| 999 | +router.use('/blockentropy', blockentropy); | |
| 916 | 1000 | |
| 917 | 1001 | module.exports = { router }; |