diff --git a/public/index.html b/public/index.html index 214ad50a4..2e2fc6671 100644 --- a/public/index.html +++ b/public/index.html @@ -1018,11 +1018,67 @@ Single-line mode +
+ +
+
+

Mirostat

+
+
+ Mirostat Mode +
+
+
+ +
+
+
+ select +
+
+
+
+
+
+ Mirostat Tau +
+
+
+ +
+
+
+ select +
+
+
+
+
+
+ Mirostat Eta +
+
+
+ +
+
+
+ select +
+
+
+
+
Samplers Order
-
+
Samplers will be applied in a top-down order. Use with caution.
@@ -1240,7 +1296,7 @@
Samplers Order
-
+
Samplers will be applied in a top-down order. Use with caution.
@@ -2134,7 +2190,45 @@
+ +
+

Instruct Mode diff --git a/public/script.js b/public/script.js index aad3a8893..4eaafa840 100644 --- a/public/script.js +++ b/public/script.js @@ -6,9 +6,8 @@ import { loadKoboldSettings, formatKoboldUrl, getKoboldGenerationData, - canUseKoboldStopSequence, - canUseKoboldStreaming, - canUseKoboldTokenization, + kai_flags, + setKoboldFlags, } from "./scripts/kai-settings.js"; import { @@ -808,9 +807,7 @@ async function getStatus() { // determine if we can use stop sequence and streaming if (main_api === "kobold" || main_api === "koboldhorde") { - kai_settings.use_stop_sequence = canUseKoboldStopSequence(data.version); - kai_settings.can_use_streaming = canUseKoboldStreaming(data.koboldVersion); - kai_settings.can_use_tokenization = canUseKoboldTokenization(data.koboldVersion); + setKoboldFlags(data.version, data.koboldVersion); } // We didn't get a 200 status code, but the endpoint has an explanation. Which means it DID connect, but I digress. @@ -2026,7 +2023,7 @@ function baseChatReplace(value, name1, name2) { function isStreamingEnabled() { return ((main_api == 'openai' && oai_settings.stream_openai && oai_settings.chat_completion_source !== chat_completion_sources.SCALE && oai_settings.chat_completion_source !== chat_completion_sources.AI21) - || (main_api == 'kobold' && kai_settings.streaming_kobold && kai_settings.can_use_streaming) + || (main_api == 'kobold' && kai_settings.streaming_kobold && kai_flags.can_use_streaming) || (main_api == 'novel' && nai_settings.streaming_novel) || (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming)) && !isMultigenEnabled(); // Multigen has a quasi-streaming mode which breaks the real streaming @@ -2318,7 +2315,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject, return; } - if (main_api == 'kobold' && kai_settings.streaming_kobold && !kai_settings.can_use_streaming) { + if (main_api == 'kobold' && kai_settings.streaming_kobold && !kai_flags.can_use_streaming) { toastr.error('Streaming is enabled, but the version of Kobold used does not support token streaming.', undefined, { timeOut: 10000, preventDuplicates: true, }); is_send_press = false; return; diff --git a/public/scripts/kai-settings.js b/public/scripts/kai-settings.js index 726900a8a..4dbfc366b 100644 --- a/public/scripts/kai-settings.js +++ b/public/scripts/kai-settings.js @@ -20,15 +20,29 @@ export const kai_settings = { tfs: 1, rep_pen_slope: 0.9, single_line: false, - use_stop_sequence: false, - can_use_tokenization: false, streaming_kobold: false, sampler_order: [0, 1, 2, 3, 4, 5, 6], + mirostat: 0, + mirostat_tau: 5.0, + mirostat_eta: 0.1, + use_default_badwordids: true, }; +export const kai_flags = { + can_use_tokenization: false, + can_use_stop_sequence: false, + can_use_streaming: false, + can_use_default_badwordids: false, + can_use_mirostat: false, +}; + +const defaultValues = Object.freeze(structuredClone(kai_settings)); + const MIN_STOP_SEQUENCE_VERSION = '1.2.2'; +const MIN_UNBAN_VERSION = '1.2.4'; const MIN_STREAMING_KCPPVERSION = '1.30'; const MIN_TOKENIZATION_KCPPVERSION = '1.41'; +const MIN_MIROSTAT_KCPPVERSION = '1.35'; const KOBOLDCPP_ORDER = [6, 0, 1, 3, 4, 2, 5]; export function formatKoboldUrl(value) { @@ -44,16 +58,16 @@ export function formatKoboldUrl(value) { export function loadKoboldSettings(preset) { for (const name of Object.keys(kai_settings)) { - const value = preset[name]; + const value = preset[name] ?? defaultValues[name]; const slider = sliders.find(x => x.name === name); - if (value === undefined || !slider) { + if (!slider) { continue; } const formattedValue = slider.format(value); - slider.setValue(preset[name]); - $(slider.sliderId).val(preset[name]); + slider.setValue(value); + $(slider.sliderId).val(value); $(slider.counterId).text(formattedValue); } @@ -66,6 +80,10 @@ export function loadKoboldSettings(preset) { kai_settings.streaming_kobold = preset.streaming_kobold; $('#streaming_kobold').prop('checked', kai_settings.streaming_kobold); } + if (preset.hasOwnProperty('use_default_badwordids')) { + kai_settings.use_default_badwordids = preset.use_default_badwordids; + $('#use_default_badwordids').prop('checked', kai_settings.use_default_badwordids); + } } export function getKoboldGenerationData(finalPrompt, this_settings, this_amount_gen, this_max_context, isImpersonate, type) { @@ -94,9 +112,13 @@ export function getKoboldGenerationData(finalPrompt, this_settings, this_amount_ s7: sampler_order[6], use_world_info: false, singleline: kai_settings.single_line, - stop_sequence: kai_settings.use_stop_sequence ? getStoppingStrings(isImpersonate, false) : undefined, - streaming: kai_settings.streaming_kobold && kai_settings.can_use_streaming && type !== 'quiet', - can_abort: kai_settings.can_use_streaming, + stop_sequence: kai_flags.can_use_stop_sequence ? getStoppingStrings(isImpersonate, false) : undefined, + streaming: kai_settings.streaming_kobold && kai_flags.can_use_streaming && type !== 'quiet', + can_abort: kai_flags.can_use_streaming, + mirostat: kai_flags.can_use_mirostat ? kai_settings.mirostat : undefined, + mirostat_tau: kai_flags.can_use_mirostat ? kai_settings.mirostat_tau : undefined, + mirostat_eta: kai_flags.can_use_mirostat ? kai_settings.mirostat_eta : undefined, + use_default_badwordids: kai_flags.can_use_default_badwordids ? kai_settings.use_default_badwordids : undefined, }; return generate_data; } @@ -213,24 +235,62 @@ const sliders = [ counterId: "#no_op_selector", format: (val) => val, setValue: (val) => { sortItemsByOrder(val); kai_settings.sampler_order = val; }, - } + }, + { + name: "mirostat", + sliderId: "#mirostat_mode_kobold", + counterId: "#mirostat_mode_counter_kobold", + format: (val) => val, + setValue: (val) => { kai_settings.mirostat = Number(val); }, + }, + { + name: "mirostat_tau", + sliderId: "#mirostat_tau_kobold", + counterId: "#mirostat_tau_counter_kobold", + format: (val) => val, + setValue: (val) => { kai_settings.mirostat_tau = Number(val); }, + }, + { + name: "mirostat_eta", + sliderId: "#mirostat_eta_kobold", + counterId: "#mirostat_eta_counter_kobold", + format: (val) => val, + setValue: (val) => { kai_settings.mirostat_eta = Number(val); }, + }, ]; +export function setKoboldFlags(version, koboldVersion) { + kai_flags.can_use_stop_sequence = canUseKoboldStopSequence(version); + kai_flags.can_use_streaming = canUseKoboldStreaming(koboldVersion); + kai_flags.can_use_tokenization = canUseKoboldTokenization(koboldVersion); + kai_flags.can_use_default_badwordids = canUseDefaultBadwordIds(version); + kai_flags.can_use_mirostat = canUseMirostat(koboldVersion); +} + /** * Determines if the Kobold stop sequence can be used with the given version. * @param {string} version KoboldAI version to check. * @returns {boolean} True if the Kobold stop sequence can be used, false otherwise. */ -export function canUseKoboldStopSequence(version) { +function canUseKoboldStopSequence(version) { return (version || '0.0.0').localeCompare(MIN_STOP_SEQUENCE_VERSION, undefined, { numeric: true, sensitivity: 'base' }) > -1; } +/** + * Determines if the Kobold default badword ids can be used with the given version. + * @param {string} version KoboldAI version to check. + * @returns {boolean} True if the Kobold default badword ids can be used, false otherwise. + */ +function canUseDefaultBadwordIds(version) { + return (version || '0.0.0').localeCompare(MIN_UNBAN_VERSION, undefined, { numeric: true, sensitivity: 'base' }) > -1; +} + /** * Determines if the Kobold streaming API can be used with the given version. * @param {{ result: string; version: string; }} koboldVersion KoboldAI version object. * @returns {boolean} True if the Kobold streaming API can be used, false otherwise. */ -export function canUseKoboldStreaming(koboldVersion) { +function canUseKoboldStreaming(koboldVersion) { if (koboldVersion && koboldVersion.result == 'KoboldCpp') { return (koboldVersion.version || '0.0').localeCompare(MIN_STREAMING_KCPPVERSION, undefined, { numeric: true, sensitivity: 'base' }) > -1; } else return false; @@ -241,12 +301,18 @@ export function canUseKoboldStreaming(koboldVersion) { * @param {{ result: string; version: string; }} koboldVersion KoboldAI version object. * @returns {boolean} True if the Kobold tokenization API can be used, false otherwise. */ -export function canUseKoboldTokenization(koboldVersion) { +function canUseKoboldTokenization(koboldVersion) { if (koboldVersion && koboldVersion.result == 'KoboldCpp') { return (koboldVersion.version || '0.0').localeCompare(MIN_TOKENIZATION_KCPPVERSION, undefined, { numeric: true, sensitivity: 'base' }) > -1; } else return false; } +function canUseMirostat(koboldVersion) { + if (koboldVersion && koboldVersion.result == 'KoboldCpp') { + return (koboldVersion.version || '0.0').localeCompare(MIN_MIROSTAT_KCPPVERSION, undefined, { numeric: true, sensitivity: 'base' }) > -1; + } else return false; +} + /** * Sorts the sampler items by the given order. * @param {any[]} orderArray Sampler order array. @@ -274,17 +340,23 @@ jQuery(function () { }); $('#single_line').on("input", function () { - const value = $(this).prop('checked'); + const value = !!$(this).prop('checked'); kai_settings.single_line = value; saveSettingsDebounced(); }); $('#streaming_kobold').on("input", function () { - const value = $(this).prop('checked'); + const value = !!$(this).prop('checked'); kai_settings.streaming_kobold = value; saveSettingsDebounced(); }); + $('#use_default_badwordids').on("input", function () { + const value = !!$(this).prop('checked'); + kai_settings.use_default_badwordids = value; + saveSettingsDebounced(); + }); + $('#kobold_order').sortable({ delay: getSortableDelay(), stop: function () {