Add vLLM as multimodal captioning source
| @@ -356,6 +356,7 @@ jQuery(async function () { | |||
| 356 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'llamacpp' && textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) || | 356 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'llamacpp' && textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) || |
| 357 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'ooba' && textgenerationwebui_settings.server_urls[textgen_types.OOBA]) || | 357 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'ooba' && textgenerationwebui_settings.server_urls[textgen_types.OOBA]) || |
| 358 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'koboldcpp' && textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]) || | 358 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'koboldcpp' && textgenerationwebui_settings.server_urls[textgen_types.KOBOLDCPP]) || |
| 359 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'vllm' && textgenerationwebui_settings.server_urls[textgen_types.VLLM]) || | ||
| 359 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'custom') || | 360 | (extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'custom') || |
| 360 | extension_settings.caption.source === 'local' || | 361 | extension_settings.caption.source === 'local' || |
| 361 | extension_settings.caption.source === 'horde'; | 362 | extension_settings.caption.source === 'horde'; |
| @@ -26,6 +26,7 @@ | |||
| 26 | <option value="openai">OpenAI</option> | 26 | <option value="openai">OpenAI</option> |
| 27 | <option value="openrouter">OpenRouter</option> | 27 | <option value="openrouter">OpenRouter</option> |
| 28 | <option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option> | 28 | <option value="ooba" data-i18n="Text Generation WebUI (oobabooga)">Text Generation WebUI (oobabooga)</option> |
| 29 | <option value="vllm">vLLM</option> | ||
| 29 | </select> | 30 | </select> |
| 30 | </div> | 31 | </div> |
| 31 | <div class="flex1 flex-container flexFlowColumn flexNoGap"> | 32 | <div class="flex1 flex-container flexFlowColumn flexNoGap"> |
| @@ -66,6 +67,7 @@ | |||
| 66 | <option data-type="llamacpp" value="llamacpp_current" data-i18n="currently_loaded">[Currently loaded]</option> | 67 | <option data-type="llamacpp" value="llamacpp_current" data-i18n="currently_loaded">[Currently loaded]</option> |
| 67 | <option data-type="ooba" value="ooba_current" data-i18n="currently_loaded">[Currently loaded]</option> | 68 | <option data-type="ooba" value="ooba_current" data-i18n="currently_loaded">[Currently loaded]</option> |
| 68 | <option data-type="koboldcpp" value="koboldcpp_current" data-i18n="currently_loaded">[Currently loaded]</option> | 69 | <option data-type="koboldcpp" value="koboldcpp_current" data-i18n="currently_loaded">[Currently loaded]</option> |
| 70 | <option data-type="vllm" value="vllm_current" data-i18n="currently_selected">[Currently selected]</option> | ||
| 69 | <option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option> | 71 | <option data-type="custom" value="custom_current" data-i18n="currently_selected">[Currently selected]</option> |
| 70 | </select> | 72 | </select> |
| 71 | </div> | 73 | </div> |
| @@ -34,6 +34,7 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 34 | const isCustom = extension_settings.caption.multimodal_api === 'custom'; | 34 | const isCustom = extension_settings.caption.multimodal_api === 'custom'; |
| 35 | const isOoba = extension_settings.caption.multimodal_api === 'ooba'; | 35 | const isOoba = extension_settings.caption.multimodal_api === 'ooba'; |
| 36 | const isKoboldCpp = extension_settings.caption.multimodal_api === 'koboldcpp'; | 36 | const isKoboldCpp = extension_settings.caption.multimodal_api === 'koboldcpp'; |
| 37 | const isVllm = extension_settings.caption.multimodal_api === 'vllm'; | ||
| 37 | const base64Bytes = base64Img.length * 0.75; | 38 | const base64Bytes = base64Img.length * 0.75; |
| 38 | const compressionLimit = 2 * 1024 * 1024; | 39 | const compressionLimit = 2 * 1024 * 1024; |
| 39 | if ((['google', 'openrouter'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) { | 40 | if ((['google', 'openrouter'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba || isKoboldCpp) { |
| @@ -65,6 +66,14 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 65 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]; | 66 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| 69 | if (isVllm) { | ||
| 70 | if (extension_settings.caption.multimodal_model === 'vllm_current') { | ||
| 71 | requestBody.model = textgenerationwebui_settings.vllm_model; | ||
| 72 | } | ||
| 73 | |||
| 74 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.VLLM]; | ||
| 75 | } | ||
| 76 | |||
| 68 | if (isLlamaCpp) { | 77 | if (isLlamaCpp) { |
| 69 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]; | 78 | requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]; |
| 70 | } | 79 | } |
| @@ -151,6 +160,14 @@ function throwIfInvalidModel(useReverseProxy) { | |||
| 151 | throw new Error('KoboldCpp server URL is not set.'); | 160 | throw new Error('KoboldCpp server URL is not set.'); |
| 152 | } | 161 | } |
| 153 | 162 | ||
| 163 | if (extension_settings.caption.multimodal_api === 'vllm' && !textgenerationwebui_settings.server_urls[textgen_types.VLLM]) { | ||
| 164 | throw new Error('vLLM server URL is not set.'); | ||
| 165 | } | ||
| 166 | |||
| 167 | if (extension_settings.caption.multimodal_api === 'vllm' && extension_settings.caption.multimodal_model === 'vllm_current' && !textgenerationwebui_settings.vllm_model) { | ||
| 168 | throw new Error('vLLM model is not set.'); | ||
| 169 | } | ||
| 170 | |||
| 154 | if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) { | 171 | if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) { |
| 155 | throw new Error('Custom API URL is not set.'); | 172 | throw new Error('Custom API URL is not set.'); |
| 156 | } | 173 | } |
| @@ -43,7 +43,11 @@ router.post('/caption-image', jsonParser, async (request, response) => { | |||
| 43 | key = readSecret(request.user.directories, SECRET_KEYS.KOBOLDCPP); | 43 | key = readSecret(request.user.directories, SECRET_KEYS.KOBOLDCPP); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | if (!key && !request.body.reverse_proxy && ['custom', 'ooba', 'koboldcpp'].includes(request.body.api) === false) { | 46 | if (request.body.api === 'vllm') { |
| 47 | key = readSecret(request.user.directories, SECRET_KEYS.VLLM); | ||
| 48 | } | ||
| 49 | |||
| 50 | if (!key && !request.body.reverse_proxy && ['custom', 'ooba', 'koboldcpp', 'vllm'].includes(request.body.api) === false) { | ||
| 47 | console.log('No key found for API', request.body.api); | 51 | console.log('No key found for API', request.body.api); |
| 48 | return response.sendStatus(400); | 52 | return response.sendStatus(400); |
| 49 | } | 53 | } |
| @@ -110,7 +114,7 @@ router.post('/caption-image', jsonParser, async (request, response) => { | |||
| 110 | }); | 114 | }); |
| 111 | } | 115 | } |
| 112 | 116 | ||
| 113 | if (request.body.api === 'koboldcpp') { | 117 | if (request.body.api === 'koboldcpp' || request.body.api === 'vllm') { |
| 114 | apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`; | 118 | apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`; |
| 115 | } | 119 | } |
| 116 | 120 | ||