diff --git a/public/index.html b/public/index.html
index e54069a60..79bff508c 100644
--- a/public/index.html
+++ b/public/index.html
@@ -119,7 +119,7 @@
-
+
diff --git a/public/scripts/nai-settings.js b/public/scripts/nai-settings.js
index e49b7df5a..34207ada3 100644
--- a/public/scripts/nai-settings.js
+++ b/public/scripts/nai-settings.js
@@ -5,9 +5,7 @@ import {
novelai_setting_names,
saveSettingsDebounced,
setGenerationParamsFromPreset,
- substituteParams,
} from '../script.js';
-import { getCfgPrompt } from './cfg-scale.js';
import { MAX_CONTEXT_DEFAULT, MAX_RESPONSE_DEFAULT, power_user } from './power-user.js';
import { getTextTokens, tokenizers } from './tokenizers.js';
import { getEventSourceStream } from './sse-stream.js';
@@ -61,6 +59,19 @@ const nai_tiers = {
3: 'Opus',
};
+const samplers = {
+ temperature: 0,
+ top_k: 1,
+ top_p: 2,
+ tfs: 3,
+ top_a: 4,
+ typical_p: 5,
+ // removed samplers were here
+ mirostat: 8,
+ math1: 9,
+ min_p: 10,
+};
+
let novel_data = null;
let badWordsCache = {};
const BIAS_KEY = '#novel_api-settings';
@@ -95,6 +106,37 @@ export function getKayraMaxResponseTokens() {
return maximum_output_length;
}
+export function convertNovelPreset(data) {
+ if (!data || typeof data !== 'object' || data.presetVersion !== 3 || !data.parameters || typeof data.parameters !== 'object') {
+ return data;
+ }
+
+ return {
+ max_context: 8000,
+ temperature: data.parameters.temperature,
+ max_length: data.parameters.max_length,
+ min_length: data.parameters.min_length,
+ top_k: data.parameters.top_k,
+ top_p: data.parameters.top_p,
+ top_a: data.parameters.top_a,
+ typical_p: data.parameters.typical_p,
+ tail_free_sampling: data.parameters.tail_free_sampling,
+ repetition_penalty: data.parameters.repetition_penalty,
+ repetition_penalty_range: data.parameters.repetition_penalty_range,
+ repetition_penalty_slope: data.parameters.repetition_penalty_slope,
+ repetition_penalty_frequency: data.parameters.repetition_penalty_frequency,
+ repetition_penalty_presence: data.parameters.repetition_penalty_presence,
+ phrase_rep_pen: data.parameters.phrase_rep_pen,
+ mirostat_lr: data.parameters.mirostat_lr,
+ mirostat_tau: data.parameters.mirostat_tau,
+ math1_temp: data.parameters.math1_temp,
+ math1_quad: data.parameters.math1_quad,
+ math1_quad_entropy_scale: data.parameters.math1_quad_entropy_scale,
+ min_p: data.parameters.min_p,
+ order: Array.isArray(data.parameters.order) ? data.parameters.order.filter(s => s.enabled && Object.keys(samplers).includes(s.id)).map(s => samplers[s.id]) : default_order,
+ };
+}
+
export function getNovelTier() {
return nai_tiers[novel_data?.tier] ?? 'no_connection';
}
diff --git a/public/scripts/preset-manager.js b/public/scripts/preset-manager.js
index 60f7ce07a..1fc993af4 100644
--- a/public/scripts/preset-manager.js
+++ b/public/scripts/preset-manager.js
@@ -18,6 +18,7 @@ import {
import { groups, selected_group } from './group-chats.js';
import { instruct_presets } from './instruct-mode.js';
import { kai_settings } from './kai-settings.js';
+import { convertNovelPreset } from './nai-settings.js';
import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
import { context_presets, getContextSettings, power_user } from './power-user.js';
import { SlashCommand } from './slash-commands/SlashCommand.js';
@@ -397,6 +398,10 @@ class PresetManager {
await checkForSystemPromptInInstructTemplate(name, settings);
}
+ if (this.apiId === 'novel' && settings) {
+ settings = convertNovelPreset(settings);
+ }
+
const preset = settings ?? this.getPresetSettings(name);
const response = await fetch('/api/presets/save', {