sillytavern 1.10.6 → 1.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -47,7 +47,7 @@
47
47
  "type": "git",
48
48
  "url": "https://github.com/SillyTavern/SillyTavern.git"
49
49
  },
50
- "version": "1.10.6",
50
+ "version": "1.10.7",
51
51
  "scripts": {
52
52
  "start": "node server.js",
53
53
  "start-multi": "node server.js --disableCsrf",
package/public/index.html CHANGED
@@ -234,11 +234,10 @@
234
234
  </div>
235
235
  <div class="range-block-range-and-counter">
236
236
  <div class="range-block-range">
237
- <input type="range" id="max_context" name="volume" min="512" max="4096" step="512">
237
+ <input type="range" id="max_context" name="volume" min="512" max="8192" step="64">
238
238
  </div>
239
239
  <div class="range-block-counter" data-randomization-disabled="true">
240
- <input type="number" min="512" max="4096" step="512" data-for="max_context" id="max_context_counter">
241
-
240
+ <input type="number" min="512" max="8192" step="64" data-for="max_context" id="max_context_counter">
242
241
  </div>
243
242
  </div>
244
243
  </div>
@@ -1091,6 +1090,14 @@
1091
1090
  </div>
1092
1091
  </div>
1093
1092
  <hr>
1093
+ <div class="range-block">
1094
+ <div class="range-block-title" data-i18n="Seed">
1095
+ Seed
1096
+ </div>
1097
+ <!-- Max value is 2**64 - 1 -->
1098
+ <input type="number" id="seed_kobold" class="text_pole wide100p" min="-1" value="-1" max="18446744073709551615" />
1099
+ </div>
1100
+ <hr>
1094
1101
  <div class="range-block flexFlowColumn">
1095
1102
  <div class="range-block-title">
1096
1103
  <span data-i18n="Samplers Order">Samplers Order</span>
package/public/script.js CHANGED
@@ -8815,7 +8815,7 @@ jQuery(async function () {
8815
8815
  }
8816
8816
 
8817
8817
  restoreCaretPosition($(this).get(0), caretPosition);
8818
- }, 500);
8818
+ }, 2000);
8819
8819
  })
8820
8820
 
8821
8821
  $(".user_stats_button").on('click', function () {
@@ -55,6 +55,14 @@ function downloadAssetsList(url) {
55
55
  for (const assetType of assetTypes) {
56
56
  let assetTypeMenu = $('<div />', { id: "assets_audio_ambient_div", class: "assets-list-div" });
57
57
  assetTypeMenu.append(`<h3>${assetType}</h3>`)
58
+
59
+ if (assetType == 'extension') {
60
+ assetTypeMenu.append(`
61
+ <div class="assets-list-git">
62
+ To download extensions from this page, you need to have <a href="https://git-scm.com/downloads" target="_blank">Git</a> installed.
63
+ </div>`);
64
+ }
65
+
58
66
  for (const i in availableAssets[assetType]) {
59
67
  const asset = availableAssets[assetType][i];
60
68
  const elemId = `assets_install_${assetType}_${i}`;
@@ -13,11 +13,17 @@
13
13
  padding: 5px;
14
14
  }
15
15
 
16
+ .assets-list-git {
17
+ font-size: calc(var(--mainFontSize) * 0.8);
18
+ opacity: 0.8;
19
+ margin-bottom: 1em;
20
+ }
21
+
16
22
  .assets-list-div h3 {
17
23
  text-transform: capitalize;
18
24
  }
19
25
 
20
- .assets-list-div a {
26
+ .assets-list-div i a {
21
27
  color: inherit;
22
28
  }
23
29
 
@@ -733,8 +733,9 @@ export async function installExtension(url) {
733
733
  });
734
734
 
735
735
  if (!request.ok) {
736
- toastr.info(request.statusText, 'Extension installation failed');
737
- console.error('Extension installation failed', request.status, request.statusText);
736
+ const text = await request.text();
737
+ toastr.warning(text || request.statusText, 'Extension installation failed', { timeOut: 5000 });
738
+ console.error('Extension installation failed', request.status, request.statusText, text);
738
739
  return;
739
740
  }
740
741
 
@@ -28,6 +28,7 @@ export const kai_settings = {
28
28
  mirostat_eta: 0.1,
29
29
  use_default_badwordsids: false,
30
30
  grammar: "",
31
+ seed: -1,
31
32
  };
32
33
 
33
34
  export const kai_flags = {
@@ -136,6 +137,7 @@ export function getKoboldGenerationData(finalPrompt, settings, maxLength, maxCon
136
137
  mirostat_eta: kai_flags.can_use_mirostat ? kai_settings.mirostat_eta : undefined,
137
138
  use_default_badwordsids: kai_flags.can_use_default_badwordsids ? kai_settings.use_default_badwordsids : undefined,
138
139
  grammar: kai_flags.can_use_grammar ? substituteParams(kai_settings.grammar) : undefined,
140
+ sampler_seed: kai_settings.seed >= 0 ? kai_settings.seed : undefined,
139
141
  };
140
142
  return generate_data;
141
143
  }
@@ -281,6 +283,13 @@ const sliders = [
281
283
  format: (val) => val,
282
284
  setValue: (val) => { kai_settings.grammar = val; },
283
285
  },
286
+ {
287
+ name: "seed",
288
+ sliderId: "#seed_kobold",
289
+ counterId: "#seed_counter_kobold",
290
+ format: (val) => val,
291
+ setValue: (val) => { kai_settings.seed = Number(val); },
292
+ },
284
293
  ];
285
294
 
286
295
  export function setKoboldFlags(version, koboldVersion) {
@@ -46,8 +46,9 @@ export {
46
46
 
47
47
  export const MAX_CONTEXT_DEFAULT = 8192;
48
48
  const MAX_CONTEXT_UNLOCKED = 65536;
49
- const unlockedMaxContextStep = 4096
50
- const unlockedMaxContestMin = 8192
49
+ const unlockedMaxContextStep = 256;
50
+ const maxContextMin = 512;
51
+ const maxContextStep = 64;
51
52
 
52
53
  const defaultStoryString = "{{#if system}}{{system}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}";
53
54
  const defaultExampleSeparator = '***';
@@ -1087,8 +1088,8 @@ function loadMaxContextUnlocked() {
1087
1088
  function switchMaxContextSize() {
1088
1089
  const elements = [$('#max_context'), $('#rep_pen_range'), $('#rep_pen_range_textgenerationwebui')];
1089
1090
  const maxValue = power_user.max_context_unlocked ? MAX_CONTEXT_UNLOCKED : MAX_CONTEXT_DEFAULT;
1090
- const minValue = power_user.max_context_unlocked ? unlockedMaxContestMin : 0;
1091
- const steps = power_user.max_context_unlocked ? unlockedMaxContextStep : 256;
1091
+ const minValue = power_user.max_context_unlocked ? maxContextMin : maxContextMin;
1092
+ const steps = power_user.max_context_unlocked ? unlockedMaxContextStep : maxContextStep;
1092
1093
 
1093
1094
  for (const element of elements) {
1094
1095
  element.attr('max', maxValue);
@@ -262,6 +262,7 @@ class PresetManager {
262
262
  'model_novel',
263
263
  'streaming_kobold',
264
264
  "enabled",
265
+ 'seed',
265
266
  ];
266
267
  const settings = Object.assign({}, getSettingsByApiId(this.apiId));
267
268
 
@@ -135,10 +135,10 @@ function setWorldInfoSettings(settings, data) {
135
135
 
136
136
  world_info = settings.world_info ?? {}
137
137
 
138
- $("#world_info_depth_counter").text(world_info_depth);
138
+ $("#world_info_depth_counter").val(world_info_depth);
139
139
  $("#world_info_depth").val(world_info_depth);
140
140
 
141
- $("#world_info_budget_counter").text(world_info_budget);
141
+ $("#world_info_budget_counter").val(world_info_budget);
142
142
  $("#world_info_budget").val(world_info_budget);
143
143
 
144
144
  $("#world_info_recursive").prop('checked', world_info_recursive);
@@ -150,7 +150,7 @@ function setWorldInfoSettings(settings, data) {
150
150
  $("#world_info_character_strategy").val(world_info_character_strategy);
151
151
 
152
152
  $("#world_info_budget_cap").val(world_info_budget_cap);
153
- $("#world_info_budget_cap_counter").text(world_info_budget_cap);
153
+ $("#world_info_budget_cap_counter").val(world_info_budget_cap);
154
154
 
155
155
  world_names = data.world_names?.length ? data.world_names : [];
156
156
 
@@ -2043,13 +2043,13 @@ jQuery(() => {
2043
2043
 
2044
2044
  $(document).on("input", "#world_info_depth", function () {
2045
2045
  world_info_depth = Number($(this).val());
2046
- $("#world_info_depth_counter").text($(this).val());
2046
+ $("#world_info_depth_counter").val($(this).val());
2047
2047
  saveSettings();
2048
2048
  });
2049
2049
 
2050
2050
  $(document).on("input", "#world_info_budget", function () {
2051
2051
  world_info_budget = Number($(this).val());
2052
- $("#world_info_budget_counter").text($(this).val());
2052
+ $("#world_info_budget_counter").val($(this).val());
2053
2053
  saveSettings();
2054
2054
  });
2055
2055
 
@@ -2080,7 +2080,7 @@ jQuery(() => {
2080
2080
 
2081
2081
  $('#world_info_budget_cap').on('input', function () {
2082
2082
  world_info_budget_cap = Number($(this).val());
2083
- $("#world_info_budget_cap_counter").text(world_info_budget_cap);
2083
+ $("#world_info_budget_cap_counter").val(world_info_budget_cap);
2084
2084
  saveSettings();
2085
2085
  });
2086
2086
 
package/server.js CHANGED
@@ -401,6 +401,7 @@ app.post("/generate", jsonParser, async function (request, response_generate) {
401
401
  mirostat_eta: request.body.mirostat_eta,
402
402
  mirostat_tau: request.body.mirostat_tau,
403
403
  grammar: request.body.grammar,
404
+ sampler_seed: request.body.sampler_seed,
404
405
  };
405
406
  if (!!request.body.stop_sequence) {
406
407
  this_settings['stop_sequence'] = request.body.stop_sequence;
package/src/extensions.js CHANGED
@@ -2,6 +2,7 @@ const path = require('path');
2
2
  const fs = require('fs');
3
3
  const { default: simpleGit } = require('simple-git');
4
4
  const sanitize = require('sanitize-filename');
5
+ const commandExistsSync = require('command-exists').sync;
5
6
  const { DIRECTORIES } = require('./constants');
6
7
 
7
8
  /**
@@ -61,12 +62,19 @@ function registerEndpoints(app, jsonParser) {
61
62
  * @returns {void}
62
63
  */
63
64
  app.post('/api/extensions/install', jsonParser, async (request, response) => {
64
- const git = simpleGit();
65
+ const gitExists = commandExistsSync('git');
66
+
67
+ if (!gitExists) {
68
+ return response.status(400).send('Server Error: git is not installed on the system.');
69
+ }
70
+
65
71
  if (!request.body.url) {
66
72
  return response.status(400).send('Bad Request: URL is required in the request body.');
67
73
  }
68
74
 
69
75
  try {
76
+ const git = simpleGit();
77
+
70
78
  // make sure the third-party directory exists
71
79
  if (!fs.existsSync(path.join(DIRECTORIES.extensions, 'third-party'))) {
72
80
  fs.mkdirSync(path.join(DIRECTORIES.extensions, 'third-party'));
@@ -87,7 +95,6 @@ function registerEndpoints(app, jsonParser) {
87
95
 
88
96
 
89
97
  return response.send({ version, author, display_name, extensionPath });
90
-
91
98
  } catch (error) {
92
99
  console.log('Importing custom content failed', error);
93
100
  return response.status(500).send(`Server Error: ${error.message}`);
package/statsHelpers.js CHANGED
@@ -173,8 +173,12 @@ async function loadStatsFile(chatsPath, charactersPath, recreateStats = false) {
173
173
  async function saveStatsToFile() {
174
174
  if (charStats.timestamp > lastSaveTimestamp) {
175
175
  //console.debug("Saving stats to file...");
176
- await writeFile(statsFilePath, JSON.stringify(charStats));
177
- lastSaveTimestamp = Date.now();
176
+ try {
177
+ await writeFile(statsFilePath, JSON.stringify(charStats));
178
+ lastSaveTimestamp = Date.now();
179
+ } catch (error) {
180
+ console.log("Failed to save stats to file.", error);
181
+ }
178
182
  } else {
179
183
  //console.debug('Stats have not changed since last save. Skipping file write.');
180
184
  }
@@ -184,9 +188,9 @@ async function saveStatsToFile() {
184
188
  * Attempts to save charStats to a file and then terminates the process.
185
189
  * If an error occurs during the file write, it logs the error before exiting.
186
190
  */
187
- async function writeStatsToFileAndExit(charStats) {
191
+ async function writeStatsToFileAndExit() {
188
192
  try {
189
- await saveStatsToFile(charStats);
193
+ await saveStatsToFile();
190
194
  } catch (err) {
191
195
  console.error("Failed to write stats to file:", err);
192
196
  } finally {