Merge pull request #3112 from kallewoof/202411-backend-maxctx feature: allow auto-use of max context size given by backend
Signed| @@ -2566,15 +2566,21 @@ | |||
| 2566 | <input id="koboldcpp_api_url_text" class="text_pole wide100p" value="" autocomplete="off" data-server-history="koboldcpp"> | 2566 | <input id="koboldcpp_api_url_text" class="text_pole wide100p" value="" autocomplete="off" data-server-history="koboldcpp"> |
| 2567 | </div> | 2567 | </div> |
| 2568 | </div> | 2568 | </div> |
| 2569 | <div class="flex-container flexFlowColumn marginTopBot5"> | ||
| 2570 | <label data-tg-type="ooba" class="checkbox_label" for="bypass_status_check_textgenerationwebui"> | ||
| 2571 | <input type="checkbox" id="bypass_status_check_textgenerationwebui" /> | ||
| 2572 | <span data-i18n="Bypass status check">Bypass status check</span> | ||
| 2573 | </label> | ||
| 2574 | <label data-tg-type="koboldcpp, llamacpp" class="checkbox_label" for="context_size_derived"> | ||
| 2575 | <input type="checkbox" id="context_size_derived" /> | ||
| 2576 | <span data-i18n="Derive context size from backend">Derive context size from backend</span> | ||
| 2577 | </label> | ||
| 2578 | </div> | ||
| 2569 | <div class="flex-container"> | 2579 | <div class="flex-container"> |
| 2570 | <div id="api_button_textgenerationwebui" class="api_button menu_button menu_button_icon" type="submit" data-i18n="Connect" data-server-connect="ooba_blocking,vllm,aphrodite,tabby,koboldcpp,ollama,llamacpp,huggingface">Connect</div> | 2580 | <div id="api_button_textgenerationwebui" class="api_button menu_button menu_button_icon" type="submit" data-i18n="Connect" data-server-connect="ooba_blocking,vllm,aphrodite,tabby,koboldcpp,ollama,llamacpp,huggingface">Connect</div> |
| 2571 | <div data-tg-type="openrouter" class="menu_button menu_button_icon openrouter_authorize" title="Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai" data-i18n="Authorize;[title]Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai">Authorize</div> | 2581 | <div data-tg-type="openrouter" class="menu_button menu_button_icon openrouter_authorize" title="Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai" data-i18n="Authorize;[title]Get your OpenRouter API token using OAuth flow. You will be redirected to openrouter.ai">Authorize</div> |
| 2572 | <div class="api_loading menu_button menu_button_icon" data-i18n="Cancel">Cancel</div> | 2582 | <div class="api_loading menu_button menu_button_icon" data-i18n="Cancel">Cancel</div> |
| 2573 | </div> | 2583 | </div> |
| 2574 | <label data-tg-type="ooba" class="checkbox_label margin-bot-10px" for="bypass_status_check_textgenerationwebui"> | ||
| 2575 | <input type="checkbox" id="bypass_status_check_textgenerationwebui" /> | ||
| 2576 | <span data-i18n="Bypass status check">Bypass status check</span> | ||
| 2577 | </label> | ||
| 2578 | </form> | 2584 | </form> |
| 2579 | <div class="online_status"> | 2585 | <div class="online_status"> |
| 2580 | <div class="online_status_indicator"></div> | 2586 | <div class="online_status_indicator"></div> |
| @@ -1238,8 +1238,9 @@ async function getStatusTextgen() { | |||
| 1238 | 1238 | ||
| 1239 | const wantsInstructDerivation = (power_user.instruct.enabled && power_user.instruct.derived); | 1239 | const wantsInstructDerivation = (power_user.instruct.enabled && power_user.instruct.derived); |
| 1240 | const wantsContextDerivation = power_user.context_derived; | 1240 | const wantsContextDerivation = power_user.context_derived; |
| 1241 | const wantsContextSize = power_user.context_size_derived; | ||
| 1241 | const supportsChatTemplate = [textgen_types.KOBOLDCPP, textgen_types.LLAMACPP].includes(textgen_settings.type); | 1242 | const supportsChatTemplate = [textgen_types.KOBOLDCPP, textgen_types.LLAMACPP].includes(textgen_settings.type); |
| 1242 | if (supportsChatTemplate && (wantsInstructDerivation || wantsContextDerivation)) { | 1243 | if (supportsChatTemplate && (wantsInstructDerivation || wantsContextDerivation || wantsContextSize)) { |
| 1243 | const response = await fetch('/api/backends/text-completions/props', { | 1244 | const response = await fetch('/api/backends/text-completions/props', { |
| 1244 | method: 'POST', | 1245 | method: 'POST', |
| 1245 | headers: getRequestHeaders(), | 1246 | headers: getRequestHeaders(), |
| @@ -1253,6 +1254,17 @@ async function getStatusTextgen() { | |||
| 1253 | const data = await response.json(); | 1254 | const data = await response.json(); |
| 1254 | if (data) { | 1255 | if (data) { |
| 1255 | const { chat_template, chat_template_hash } = data; | 1256 | const { chat_template, chat_template_hash } = data; |
| 1257 | if (wantsContextSize && 'default_generation_settings' in data) { | ||
| 1258 | const backend_max_context = data['default_generation_settings']['n_ctx']; | ||
| 1259 | const old_value = max_context; | ||
| 1260 | if (max_context !== backend_max_context) { | ||
| 1261 | setGenerationParamsFromPreset({ max_length: backend_max_context }); | ||
| 1262 | } | ||
| 1263 | if (old_value !== max_context) { | ||
| 1264 | console.log(`Auto-switched max context from ${old_value} to ${max_context}`); | ||
| 1265 | toastr.info(`${old_value} ⇒ ${max_context}`, 'Context Size Changed'); | ||
| 1266 | } | ||
| 1267 | } | ||
| 1256 | console.log(`We have chat template ${chat_template.split('\n')[0]}...`); | 1268 | console.log(`We have chat template ${chat_template.split('\n')[0]}...`); |
| 1257 | const templates = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash); | 1269 | const templates = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash); |
| 1258 | if (templates) { | 1270 | if (templates) { |
| @@ -6822,6 +6834,10 @@ export async function saveSettings(type) { | |||
| 6822 | }); | 6834 | }); |
| 6823 | } | 6835 | } |
| 6824 | 6836 | ||
| 6837 | /** | ||
| 6838 | * Sets the generation parameters from a preset object. | ||
| 6839 | * @param {{ genamt?: number, max_length?: number }} preset Preset object | ||
| 6840 | */ | ||
| 6825 | export function setGenerationParamsFromPreset(preset) { | 6841 | export function setGenerationParamsFromPreset(preset) { |
| 6826 | const needsUnlock = (preset.max_length ?? max_context) > MAX_CONTEXT_DEFAULT || (preset.genamt ?? amount_gen) > MAX_RESPONSE_DEFAULT; | 6842 | const needsUnlock = (preset.max_length ?? max_context) > MAX_CONTEXT_DEFAULT || (preset.genamt ?? amount_gen) > MAX_RESPONSE_DEFAULT; |
| 6827 | $('#max_context_unlocked').prop('checked', needsUnlock).trigger('change'); | 6843 | $('#max_context_unlocked').prop('checked', needsUnlock).trigger('change'); |
| @@ -246,6 +246,7 @@ let power_user = { | |||
| 246 | }, | 246 | }, |
| 247 | 247 | ||
| 248 | context_derived: false, | 248 | context_derived: false, |
| 249 | context_size_derived: false, | ||
| 249 | 250 | ||
| 250 | sysprompt: { | 251 | sysprompt: { |
| 251 | enabled: true, | 252 | enabled: true, |
| @@ -1482,6 +1483,7 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1482 | $('#example_messages_behavior').val(getExampleMessagesBehavior()); | 1483 | $('#example_messages_behavior').val(getExampleMessagesBehavior()); |
| 1483 | $(`#example_messages_behavior option[value="${getExampleMessagesBehavior()}"]`).prop('selected', true); | 1484 | $(`#example_messages_behavior option[value="${getExampleMessagesBehavior()}"]`).prop('selected', true); |
| 1484 | $('#context_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.context_derived); | 1485 | $('#context_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.context_derived); |
| 1486 | $('#context_size_derived').prop('checked', !!power_user.context_size_derived); | ||
| 1485 | 1487 | ||
| 1486 | $('#console_log_prompts').prop('checked', power_user.console_log_prompts); | 1488 | $('#console_log_prompts').prop('checked', power_user.console_log_prompts); |
| 1487 | $('#request_token_probabilities').prop('checked', power_user.request_token_probabilities); | 1489 | $('#request_token_probabilities').prop('checked', power_user.request_token_probabilities); |
| @@ -3079,6 +3081,16 @@ $(document).ready(() => { | |||
| 3079 | $('#context_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.context_derived); | 3081 | $('#context_derived').parent().find('i').toggleClass('toggleEnabled', !!power_user.context_derived); |
| 3080 | }); | 3082 | }); |
| 3081 | 3083 | ||
| 3084 | $('#context_size_derived').on('input', function () { | ||
| 3085 | const value = !!$(this).prop('checked'); | ||
| 3086 | power_user.context_size_derived = value; | ||
| 3087 | saveSettingsDebounced(); | ||
| 3088 | }); | ||
| 3089 | |||
| 3090 | $('#context_size_derived').on('change', function () { | ||
| 3091 | $('#context_size_derived').prop('checked', !!power_user.context_size_derived); | ||
| 3092 | }); | ||
| 3093 | |||
| 3082 | $('#always-force-name2-checkbox').change(function () { | 3094 | $('#always-force-name2-checkbox').change(function () { |
| 3083 | power_user.always_force_name2 = !!$(this).prop('checked'); | 3095 | power_user.always_force_name2 = !!$(this).prop('checked'); |
| 3084 | saveSettingsDebounced(); | 3096 | saveSettingsDebounced(); |
| @@ -152,7 +152,7 @@ router.post('/status', jsonParser, async function (request, response) { | |||
| 152 | 152 | ||
| 153 | if (!modelsReply.ok) { | 153 | if (!modelsReply.ok) { |
| 154 | console.log('Models endpoint is offline.'); | 154 | console.log('Models endpoint is offline.'); |
| 155 | return response.status(400); | 155 | return response.sendStatus(400); |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | /** @type {any} */ | 158 | /** @type {any} */ |
| @@ -173,7 +173,7 @@ router.post('/status', jsonParser, async function (request, response) { | |||
| 173 | 173 | ||
| 174 | if (!Array.isArray(data.data)) { | 174 | if (!Array.isArray(data.data)) { |
| 175 | console.log('Models response is not an array.'); | 175 | console.log('Models response is not an array.'); |
| 176 | return response.status(400); | 176 | return response.sendStatus(400); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | const modelIds = data.data.map(x => x.id); | 179 | const modelIds = data.data.map(x => x.id); |
| @@ -224,7 +224,7 @@ router.post('/status', jsonParser, async function (request, response) { | |||
| 224 | return response.send({ result, data: data.data }); | 224 | return response.send({ result, data: data.data }); |
| 225 | } catch (error) { | 225 | } catch (error) { |
| 226 | console.error(error); | 226 | console.error(error); |
| 227 | return response.status(500); | 227 | return response.sendStatus(500); |
| 228 | } | 228 | } |
| 229 | }); | 229 | }); |
| 230 | 230 | ||
| @@ -244,7 +244,7 @@ router.post('/props', jsonParser, async function (request, response) { | |||
| 244 | const propsReply = await fetch(propsUrl, args); | 244 | const propsReply = await fetch(propsUrl, args); |
| 245 | 245 | ||
| 246 | if (!propsReply.ok) { | 246 | if (!propsReply.ok) { |
| 247 | return response.status(400); | 247 | return response.sendStatus(400); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | /** @type {any} */ | 250 | /** @type {any} */ |
| @@ -258,7 +258,7 @@ router.post('/props', jsonParser, async function (request, response) { | |||
| 258 | return response.send(props); | 258 | return response.send(props); |
| 259 | } catch (error) { | 259 | } catch (error) { |
| 260 | console.error(error); | 260 | console.error(error); |
| 261 | return response.status(500); | 261 | return response.sendStatus(500); |
| 262 | } | 262 | } |
| 263 | }); | 263 | }); |
| 264 | 264 | ||
| @@ -450,7 +450,7 @@ ollama.post('/download', jsonParser, async function (request, response) { | |||
| 450 | return response.send({ ok: true }); | 450 | return response.send({ ok: true }); |
| 451 | } catch (error) { | 451 | } catch (error) { |
| 452 | console.error(error); | 452 | console.error(error); |
| 453 | return response.status(500); | 453 | return response.sendStatus(500); |
| 454 | } | 454 | } |
| 455 | }); | 455 | }); |
| 456 | 456 | ||
| @@ -493,7 +493,7 @@ ollama.post('/caption-image', jsonParser, async function (request, response) { | |||
| 493 | return response.send({ caption }); | 493 | return response.send({ caption }); |
| 494 | } catch (error) { | 494 | } catch (error) { |
| 495 | console.error(error); | 495 | console.error(error); |
| 496 | return response.status(500); | 496 | return response.sendStatus(500); |
| 497 | } | 497 | } |
| 498 | }); | 498 | }); |
| 499 | 499 | ||
| @@ -540,7 +540,7 @@ llamacpp.post('/caption-image', jsonParser, async function (request, response) { | |||
| 540 | 540 | ||
| 541 | } catch (error) { | 541 | } catch (error) { |
| 542 | console.error(error); | 542 | console.error(error); |
| 543 | return response.status(500); | 543 | return response.sendStatus(500); |
| 544 | } | 544 | } |
| 545 | }); | 545 | }); |
| 546 | 546 | ||
| @@ -569,7 +569,7 @@ llamacpp.post('/props', jsonParser, async function (request, response) { | |||
| 569 | 569 | ||
| 570 | } catch (error) { | 570 | } catch (error) { |
| 571 | console.error(error); | 571 | console.error(error); |
| 572 | return response.status(500); | 572 | return response.sendStatus(500); |
| 573 | } | 573 | } |
| 574 | }); | 574 | }); |
| 575 | 575 | ||
| @@ -619,7 +619,7 @@ llamacpp.post('/slots', jsonParser, async function (request, response) { | |||
| 619 | 619 | ||
| 620 | } catch (error) { | 620 | } catch (error) { |
| 621 | console.error(error); | 621 | console.error(error); |
| 622 | return response.status(500); | 622 | return response.sendStatus(500); |
| 623 | } | 623 | } |
| 624 | }); | 624 | }); |
| 625 | 625 | ||
| @@ -665,7 +665,7 @@ tabby.post('/download', jsonParser, async function (request, response) { | |||
| 665 | return response.send({ ok: true }); | 665 | return response.send({ ok: true }); |
| 666 | } catch (error) { | 666 | } catch (error) { |
| 667 | console.error(error); | 667 | console.error(error); |
| 668 | return response.status(500); | 668 | return response.sendStatus(500); |
| 669 | } | 669 | } |
| 670 | }); | 670 | }); |
| 671 | 671 | ||