Merge pull request #3112 from kallewoof/202411-backend-maxctx feature: allow auto-use of max context size given by backend

39c3924b3faa9ed92b2dd35f67c133e54b81db2d

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
4 files changed, +50 -16Showing whitespace changes
public/index.html+10 -4
@@ -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>
public/script.js+17 -1
@@ -1238,8 +1238,9 @@ async function getStatusTextgen() {
12381238
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}
68246836
6837/**
6838 * Sets the generation parameters from a preset object.
6839 * @param {{ genamt?: number, max_length?: number }} preset Preset object
6840 */
6825export function setGenerationParamsFromPreset(preset) {6841export 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');
public/scripts/power-user.js+12 -0
@@ -246,6 +246,7 @@ let power_user = {
246 },246 },
247247
248 context_derived: false,248 context_derived: false,
249 context_size_derived: false,
249250
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);
14851487
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 });
30813083
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();
src/endpoints/backends/text-completions.js+11 -11
@@ -152,7 +152,7 @@ router.post('/status', jsonParser, async function (request, response) {
152152
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 }
157157
158 /** @type {any} */158 /** @type {any} */
@@ -173,7 +173,7 @@ router.post('/status', jsonParser, async function (request, response) {
173173
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 }
178178
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});
230230
@@ -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);
245245
246 if (!propsReply.ok) {246 if (!propsReply.ok) {
247 return response.status(400);247 return response.sendStatus(400);
248 }248 }
249249
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});
264264
@@ -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});
456456
@@ -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});
499499
@@ -540,7 +540,7 @@ llamacpp.post('/caption-image', jsonParser, async function (request, response) {
540540
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});
546546
@@ -569,7 +569,7 @@ llamacpp.post('/props', jsonParser, async function (request, response) {
569569
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});
575575
@@ -619,7 +619,7 @@ llamacpp.post('/slots', jsonParser, async function (request, response) {
619619
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});
625625
@@ -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});
671671