Move text completion settings to respective module (#4239)

This commit is contained in:
Cohee
2025-07-06 16:32:48 +03:00
committed by GitHub
parent 3d488a5e7b
commit c51ce1d018
2 changed files with 187 additions and 200 deletions
+5 -196
View File
@@ -30,10 +30,9 @@ import {
generateTextGenWithStreaming,
getTextGenGenerationData,
textgen_types,
getTextGenServer,
validateTextGenUrl,
parseTextgenLogprobs,
parseTabbyLogprobs,
initTextGenSettings,
} from './scripts/textgen-settings.js';
import {
@@ -206,12 +205,7 @@ import {
tag_import_setting,
applyCharacterTagsToMessageDivs,
} from './scripts/tags.js';
import {
SECRET_KEYS,
initSecrets,
readSecretState,
writeSecret,
} from './scripts/secrets.js';
import { initSecrets, readSecretState } from './scripts/secrets.js';
import { EventEmitter } from './lib/eventemitter.js';
import { markdownExclusionExt } from './scripts/showdown-exclusion.js';
import { markdownUnderscoreExt } from './scripts/showdown-underscore.js';
@@ -227,14 +221,13 @@ import {
formatInstructModePrompt,
formatInstructModeExamples,
getInstructStoppingSequences,
autoSelectInstructPreset,
formatInstructModeSystemPrompt,
selectInstructPreset,
instruct_presets,
selectContextPreset,
} from './scripts/instruct-mode.js';
import { initLocales, t } from './scripts/i18n.js';
import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, initTokenizers, saveTokenCache, TOKENIZER_SUPPORTED_KEY } from './scripts/tokenizers.js';
import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, initTokenizers, saveTokenCache } from './scripts/tokenizers.js';
import {
user_avatar,
getUserAvatars,
@@ -249,20 +242,7 @@ import {
import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_settings } from './scripts/backgrounds.js';
import { hideLoader, showLoader } from './scripts/loader.js';
import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js';
import {
loadFeatherlessModels,
loadMancerModels,
loadOllamaModels,
loadTogetherAIModels,
loadInfermaticAIModels,
loadOpenRouterModels,
loadVllmModels,
loadAphroditeModels,
loadDreamGenModels,
initTextGenModels,
loadTabbyModels,
loadGenericModels,
} from './scripts/textgen-models.js';
import { initTextGenModels } from './scripts/textgen-models.js';
import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, preserveNeutralChat, restoreNeutralChat, formatCreatorNotes, initChatUtilities, addDOMPurifyHooks } from './scripts/chats.js';
import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';
import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';
@@ -290,7 +270,6 @@ import { applyBrowserFixes } from './scripts/browser-fixes.js';
import { initServerHistory } from './scripts/server-history.js';
import { initSettingsSearch } from './scripts/setting-search.js';
import { initBulkEdit } from './scripts/bulk-edit.js';
import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
import { getContext } from './scripts/st-context.js';
import { extractReasoningFromData, initReasoning, parseReasoningInSwipes, PromptReasoning, ReasoningHandler, removeReasoningFromString, updateReasoningUI } from './scripts/reasoning.js';
import { accountStorage } from './scripts/util/AccountStorage.js';
@@ -880,6 +859,7 @@ async function firstLoadInit() {
initDefaultSlashCommands();
initTextGenModels();
initOpenAI();
initTextGenSettings();
initKoboldSettings();
initNovelAISettings();
initSystemPrompts();
@@ -993,145 +973,6 @@ async function getStatusHorde() {
return resultCheckStatus();
}
async function getStatusTextgen() {
const url = '/api/backends/text-completions/status';
const endpoint = getTextGenServer();
if (!endpoint) {
console.warn('No endpoint for status check');
setOnlineStatus('no_connection');
return resultCheckStatus();
}
if ([textgen_types.GENERIC, textgen_types.OOBA].includes(textgen_settings.type) && textgen_settings.bypass_status_check) {
setOnlineStatus(t`Status check bypassed`);
return resultCheckStatus();
}
try {
const response = await fetch(url, {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
api_server: endpoint,
api_type: textgen_settings.type,
}),
signal: abortStatusCheck.signal,
});
const data = await response.json();
if (textgen_settings.type === textgen_types.MANCER) {
loadMancerModels(data?.data);
setOnlineStatus(textgen_settings.mancer_model);
} else if (textgen_settings.type === textgen_types.TOGETHERAI) {
loadTogetherAIModels(data?.data);
setOnlineStatus(textgen_settings.togetherai_model);
} else if (textgen_settings.type === textgen_types.OLLAMA) {
loadOllamaModels(data?.data);
setOnlineStatus(textgen_settings.ollama_model || t`Connected`);
} else if (textgen_settings.type === textgen_types.INFERMATICAI) {
loadInfermaticAIModels(data?.data);
setOnlineStatus(textgen_settings.infermaticai_model);
} else if (textgen_settings.type === textgen_types.DREAMGEN) {
loadDreamGenModels(data?.data);
setOnlineStatus(textgen_settings.dreamgen_model);
} else if (textgen_settings.type === textgen_types.OPENROUTER) {
loadOpenRouterModels(data?.data);
setOnlineStatus(textgen_settings.openrouter_model);
} else if (textgen_settings.type === textgen_types.VLLM) {
loadVllmModels(data?.data);
setOnlineStatus(textgen_settings.vllm_model);
} else if (textgen_settings.type === textgen_types.APHRODITE) {
loadAphroditeModels(data?.data);
setOnlineStatus(textgen_settings.aphrodite_model);
} else if (textgen_settings.type === textgen_types.FEATHERLESS) {
loadFeatherlessModels(data?.data);
setOnlineStatus(textgen_settings.featherless_model);
} else if (textgen_settings.type === textgen_types.TABBY) {
loadTabbyModels(data?.data);
setOnlineStatus(textgen_settings.tabby_model || data?.result);
} else if (textgen_settings.type === textgen_types.GENERIC) {
loadGenericModels(data?.data);
setOnlineStatus(textgen_settings.generic_model || data?.result || t`Connected`);
} else {
setOnlineStatus(data?.result);
}
if (!online_status) {
setOnlineStatus('no_connection');
}
power_user.chat_template_hash = '';
// Determine instruct mode preset
const autoSelected = autoSelectInstructPreset(online_status);
const supportsTokenization = response.headers.get('x-supports-tokenization') === 'true';
supportsTokenization ? sessionStorage.setItem(TOKENIZER_SUPPORTED_KEY, 'true') : sessionStorage.removeItem(TOKENIZER_SUPPORTED_KEY);
const wantsInstructDerivation = !autoSelected && (power_user.instruct.enabled && power_user.instruct_derived);
const wantsContextDerivation = !autoSelected && power_user.context_derived;
const wantsContextSize = power_user.context_size_derived;
const supportsChatTemplate = [textgen_types.KOBOLDCPP, textgen_types.LLAMACPP].includes(textgen_settings.type);
if (supportsChatTemplate && (wantsInstructDerivation || wantsContextDerivation || wantsContextSize)) {
const response = await fetch('/api/backends/text-completions/props', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
api_server: endpoint,
api_type: textgen_settings.type,
}),
});
if (response.ok) {
const data = await response.json();
if (data) {
const { chat_template, chat_template_hash } = data;
power_user.chat_template_hash = chat_template_hash;
if (wantsContextSize && 'default_generation_settings' in data) {
const backend_max_context = data['default_generation_settings']['n_ctx'];
const old_value = max_context;
if (max_context !== backend_max_context) {
setGenerationParamsFromPreset({ max_length: backend_max_context });
}
if (old_value !== max_context) {
console.log(`Auto-switched max context from ${old_value} to ${max_context}`);
toastr.info(`${old_value}${max_context}`, 'Context Size Changed');
}
}
console.log(`We have chat template ${chat_template.split('\n')[0]}...`);
const { context, instruct } = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash);
if (wantsContextDerivation && context) {
selectContextPreset(context, { isAuto: true });
}
if (wantsInstructDerivation && power_user.instruct.enabled && instruct) {
selectInstructPreset(instruct, { isAuto: true });
}
}
}
}
// We didn't get a 200 status code, but the endpoint has an explanation. Which means it DID connect, but I digress.
if (online_status === 'no_connection' && data.response) {
toastr.error(data.response, t`API Error`, { timeOut: 5000, preventDuplicates: true });
}
} catch (err) {
if (err instanceof AbortReason) {
console.info('Status check aborted.', err.reason);
} else {
console.error('Error getting status', err);
}
setOnlineStatus('no_connection');
}
return resultCheckStatus();
}
export function startStatusLoading() {
$('.api_loading').show();
$('.api_button').addClass('disabled');
@@ -10636,38 +10477,6 @@ jQuery(async function () {
}
});
$('#api_button_textgenerationwebui').on('click', async function (e) {
const keys = [
{ id: 'api_key_mancer', secret: SECRET_KEYS.MANCER },
{ id: 'api_key_vllm', secret: SECRET_KEYS.VLLM },
{ id: 'api_key_aphrodite', secret: SECRET_KEYS.APHRODITE },
{ id: 'api_key_tabby', secret: SECRET_KEYS.TABBY },
{ id: 'api_key_togetherai', secret: SECRET_KEYS.TOGETHERAI },
{ id: 'api_key_ooba', secret: SECRET_KEYS.OOBA },
{ id: 'api_key_infermaticai', secret: SECRET_KEYS.INFERMATICAI },
{ id: 'api_key_dreamgen', secret: SECRET_KEYS.DREAMGEN },
{ id: 'api_key_openrouter-tg', secret: SECRET_KEYS.OPENROUTER },
{ id: 'api_key_koboldcpp', secret: SECRET_KEYS.KOBOLDCPP },
{ id: 'api_key_llamacpp', secret: SECRET_KEYS.LLAMACPP },
{ id: 'api_key_featherless', secret: SECRET_KEYS.FEATHERLESS },
{ id: 'api_key_huggingface', secret: SECRET_KEYS.HUGGINGFACE },
{ id: 'api_key_generic', secret: SECRET_KEYS.GENERIC },
];
for (const key of keys) {
const keyValue = String($(`#${key.id}`).val()).trim();
if (keyValue.length) {
await writeSecret(key.secret, keyValue);
}
}
validateTextGenUrl();
startStatusLoading();
main_api = 'textgenerationwebui';
saveSettingsDebounced();
getStatusTextgen();
});
const button = $('#options_button');
const menu = $('#options');
+182 -4
View File
@@ -1,22 +1,30 @@
import {
abortStatusCheck,
eventSource,
event_types,
getRequestHeaders,
getStoppingStrings,
main_api,
max_context,
online_status,
resultCheckStatus,
saveSettingsDebounced,
setGenerationParamsFromPreset,
setOnlineStatus,
startStatusLoading,
substituteParams,
} from '../script.js';
import { deriveTemplatesFromChatTemplate } from './chat-templates.js';
import { t } from './i18n.js';
import { autoSelectInstructPreset, selectContextPreset, selectInstructPreset } from './instruct-mode.js';
import { BIAS_CACHE, createNewLogitBiasEntry, displayLogitBias, getLogitBiasListResult } from './logit-bias.js';
import { power_user, registerDebugFunction } from './power-user.js';
import { SECRET_KEYS, writeSecret } from './secrets.js';
import { getEventSourceStream } from './sse-stream.js';
import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer } from './textgen-models.js';
import { ENCODE_TOKENIZERS, TEXTGEN_TOKENIZERS, getTextTokens, tokenizers } from './tokenizers.js';
import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer, loadAphroditeModels, loadDreamGenModels, loadFeatherlessModels, loadGenericModels, loadInfermaticAIModels, loadMancerModels, loadOllamaModels, loadOpenRouterModels, loadTabbyModels, loadTogetherAIModels, loadVllmModels } from './textgen-models.js';
import { ENCODE_TOKENIZERS, TEXTGEN_TOKENIZERS, TOKENIZER_SUPPORTED_KEY, getTextTokens, tokenizers } from './tokenizers.js';
import { AbortReason } from './util/AbortReason.js';
import { getSortableDelay, onlyUnique, arraysEqual } from './utils.js';
export const textgen_types = {
@@ -621,7 +629,146 @@ function sortAphroditeItemsByOrder(orderArray) {
});
}
jQuery(function () {
async function getStatusTextgen() {
const url = '/api/backends/text-completions/status';
const endpoint = getTextGenServer();
if (!endpoint) {
console.warn('No endpoint for status check');
setOnlineStatus('no_connection');
return resultCheckStatus();
}
if ([textgen_types.GENERIC, textgen_types.OOBA].includes(settings.type) && settings.bypass_status_check) {
setOnlineStatus(t`Status check bypassed`);
return resultCheckStatus();
}
try {
const response = await fetch(url, {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
api_server: endpoint,
api_type: settings.type,
}),
signal: abortStatusCheck.signal,
});
const data = await response.json();
if (settings.type === textgen_types.MANCER) {
loadMancerModels(data?.data);
setOnlineStatus(settings.mancer_model);
} else if (settings.type === textgen_types.TOGETHERAI) {
loadTogetherAIModels(data?.data);
setOnlineStatus(settings.togetherai_model);
} else if (settings.type === textgen_types.OLLAMA) {
loadOllamaModels(data?.data);
setOnlineStatus(settings.ollama_model || t`Connected`);
} else if (settings.type === textgen_types.INFERMATICAI) {
loadInfermaticAIModels(data?.data);
setOnlineStatus(settings.infermaticai_model);
} else if (settings.type === textgen_types.DREAMGEN) {
loadDreamGenModels(data?.data);
setOnlineStatus(settings.dreamgen_model);
} else if (settings.type === textgen_types.OPENROUTER) {
loadOpenRouterModels(data?.data);
setOnlineStatus(settings.openrouter_model);
} else if (settings.type === textgen_types.VLLM) {
loadVllmModels(data?.data);
setOnlineStatus(settings.vllm_model);
} else if (settings.type === textgen_types.APHRODITE) {
loadAphroditeModels(data?.data);
setOnlineStatus(settings.aphrodite_model);
} else if (settings.type === textgen_types.FEATHERLESS) {
loadFeatherlessModels(data?.data);
setOnlineStatus(settings.featherless_model);
} else if (settings.type === textgen_types.TABBY) {
loadTabbyModels(data?.data);
setOnlineStatus(settings.tabby_model || data?.result);
} else if (settings.type === textgen_types.GENERIC) {
loadGenericModels(data?.data);
setOnlineStatus(settings.generic_model || data?.result || t`Connected`);
} else {
setOnlineStatus(data?.result);
}
if (!online_status) {
setOnlineStatus('no_connection');
}
power_user.chat_template_hash = '';
// Determine instruct mode preset
const autoSelected = autoSelectInstructPreset(online_status);
const supportsTokenization = response.headers.get('x-supports-tokenization') === 'true';
supportsTokenization ? sessionStorage.setItem(TOKENIZER_SUPPORTED_KEY, 'true') : sessionStorage.removeItem(TOKENIZER_SUPPORTED_KEY);
const wantsInstructDerivation = !autoSelected && (power_user.instruct.enabled && power_user.instruct_derived);
const wantsContextDerivation = !autoSelected && power_user.context_derived;
const wantsContextSize = power_user.context_size_derived;
const supportsChatTemplate = [textgen_types.KOBOLDCPP, textgen_types.LLAMACPP].includes(settings.type);
if (supportsChatTemplate && (wantsInstructDerivation || wantsContextDerivation || wantsContextSize)) {
const response = await fetch('/api/backends/text-completions/props', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify({
api_server: endpoint,
api_type: settings.type,
}),
});
if (response.ok) {
const data = await response.json();
if (data) {
const { chat_template, chat_template_hash } = data;
power_user.chat_template_hash = chat_template_hash;
if (wantsContextSize && 'default_generation_settings' in data) {
const backend_max_context = data['default_generation_settings']['n_ctx'];
const old_value = max_context;
if (max_context !== backend_max_context) {
setGenerationParamsFromPreset({ max_length: backend_max_context });
}
if (old_value !== max_context) {
console.log(`Auto-switched max context from ${old_value} to ${max_context}`);
toastr.info(`${old_value}${max_context}`, 'Context Size Changed');
}
}
console.log(`We have chat template ${chat_template.split('\n')[0]}...`);
const { context, instruct } = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash);
if (wantsContextDerivation && context) {
selectContextPreset(context, { isAuto: true });
}
if (wantsInstructDerivation && power_user.instruct.enabled && instruct) {
selectInstructPreset(instruct, { isAuto: true });
}
}
}
}
// We didn't get a 200 status code, but the endpoint has an explanation. Which means it DID connect, but I digress.
if (online_status === 'no_connection' && data.response) {
toastr.error(data.response, t`API Error`, { timeOut: 5000, preventDuplicates: true });
}
} catch (err) {
if (err instanceof AbortReason) {
console.info('Status check aborted.', err.reason);
} else {
console.error('Error getting status', err);
}
setOnlineStatus('no_connection');
}
return resultCheckStatus();
}
export function initTextGenSettings() {
$('#send_banned_tokens_textgenerationwebui').on('change', function () {
const checked = !!$(this).prop('checked');
toggleBannedStringsKillSwitch(checked,
@@ -877,7 +1024,38 @@ jQuery(function () {
saveSettingsDebounced();
});
});
$('#api_button_textgenerationwebui').on('click', async function (e) {
const keys = [
{ id: 'api_key_mancer', secret: SECRET_KEYS.MANCER },
{ id: 'api_key_vllm', secret: SECRET_KEYS.VLLM },
{ id: 'api_key_aphrodite', secret: SECRET_KEYS.APHRODITE },
{ id: 'api_key_tabby', secret: SECRET_KEYS.TABBY },
{ id: 'api_key_togetherai', secret: SECRET_KEYS.TOGETHERAI },
{ id: 'api_key_ooba', secret: SECRET_KEYS.OOBA },
{ id: 'api_key_infermaticai', secret: SECRET_KEYS.INFERMATICAI },
{ id: 'api_key_dreamgen', secret: SECRET_KEYS.DREAMGEN },
{ id: 'api_key_openrouter-tg', secret: SECRET_KEYS.OPENROUTER },
{ id: 'api_key_koboldcpp', secret: SECRET_KEYS.KOBOLDCPP },
{ id: 'api_key_llamacpp', secret: SECRET_KEYS.LLAMACPP },
{ id: 'api_key_featherless', secret: SECRET_KEYS.FEATHERLESS },
{ id: 'api_key_huggingface', secret: SECRET_KEYS.HUGGINGFACE },
{ id: 'api_key_generic', secret: SECRET_KEYS.GENERIC },
];
for (const key of keys) {
const keyValue = String($(`#${key.id}`).val()).trim();
if (keyValue.length) {
await writeSecret(key.secret, keyValue);
}
}
validateTextGenUrl();
startStatusLoading();
saveSettingsDebounced();
getStatusTextgen();
});
}
function showTypeSpecificControls(type) {
$('[data-tg-type]').each(function () {