sillytavern 1.12.8 → 1.12.9

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.
Files changed (34) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/config.yaml +2 -0
  3. package/default/config.yaml +2 -0
  4. package/package.json +1 -1
  5. package/public/global.d.ts +2 -1
  6. package/public/index.html +8 -7
  7. package/public/jsconfig.json +2 -1
  8. package/public/script.js +76 -163
  9. package/public/scripts/char-data.js +1 -0
  10. package/public/scripts/extensions/caption/settings.html +1 -0
  11. package/public/scripts/extensions/stable-diffusion/index.js +0 -15
  12. package/public/scripts/extensions/stable-diffusion/style.css +1 -1
  13. package/public/scripts/extensions/tts/style.css +1 -1
  14. package/public/scripts/extensions.js +1 -1
  15. package/public/scripts/group-chats.js +39 -31
  16. package/public/scripts/macros.js +20 -1
  17. package/public/scripts/openai.js +6 -4
  18. package/public/scripts/power-user.js +13 -12
  19. package/public/scripts/slash-commands.js +121 -12
  20. package/public/scripts/st-context.js +171 -0
  21. package/public/scripts/templates/itemizationChat.html +11 -2
  22. package/public/scripts/templates/itemizationText.html +11 -2
  23. package/public/scripts/templates/macros.html +3 -1
  24. package/public/scripts/textgen-settings.js +11 -10
  25. package/public/scripts/tokenizers.js +20 -10
  26. package/public/scripts/tool-calling.js +1 -1
  27. package/public/style.css +8 -2
  28. package/src/endpoints/backends/chat-completions.js +1 -1
  29. package/src/endpoints/characters.js +4 -3
  30. package/src/endpoints/chats.js +74 -27
  31. package/src/endpoints/users-public.js +8 -8
  32. package/src/prompt-converters.js +1 -0
  33. package/src/util.js +3 -2
  34. package/tests/package-lock.json +3 -3
package/.eslintrc.cjs CHANGED
@@ -54,6 +54,7 @@ module.exports = {
54
54
  },
55
55
  // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined
56
56
  globals: {
57
+ globalThis: 'readonly',
57
58
  ePub: 'readonly',
58
59
  pdfjsLib: 'readonly',
59
60
  toastr: 'readonly',
package/config.yaml CHANGED
@@ -1,6 +1,8 @@
1
1
  # -- DATA CONFIGURATION --
2
2
  # Root directory for user data storage
3
3
  dataRoot: ./data
4
+ # The maximum amount of memory that parsed character cards can use in MB
5
+ cardsCacheCapacity: 100
4
6
  # -- SERVER CONFIGURATION --
5
7
  # Listen for incoming connections
6
8
  listen: false
@@ -1,6 +1,8 @@
1
1
  # -- DATA CONFIGURATION --
2
2
  # Root directory for user data storage
3
3
  dataRoot: ./data
4
+ # The maximum amount of memory that parsed character cards can use in MB
5
+ cardsCacheCapacity: 100
4
6
  # -- SERVER CONFIGURATION --
5
7
  # Listen for incoming connections
6
8
  listen: false
package/package.json CHANGED
@@ -84,7 +84,7 @@
84
84
  "type": "git",
85
85
  "url": "https://github.com/SillyTavern/SillyTavern.git"
86
86
  },
87
- "version": "1.12.8",
87
+ "version": "1.12.9",
88
88
  "scripts": {
89
89
  "start": "node server.js",
90
90
  "start:deno": "deno run --allow-run --allow-net --allow-read --allow-write --allow-sys --allow-env server.js",
@@ -1,4 +1,5 @@
1
1
  import libs from './lib';
2
+ import getContext from './scripts/st-context';
2
3
 
3
4
  // Global namespace modules
4
5
  declare var ai;
@@ -6,7 +7,7 @@ declare var pdfjsLib;
6
7
  declare var ePub;
7
8
 
8
9
  declare var SillyTavern: {
9
- getContext(): any;
10
+ getContext(): typeof getContext;
10
11
  llm: any;
11
12
  libs: typeof libs;
12
13
  };
package/public/index.html CHANGED
@@ -669,7 +669,7 @@
669
669
  </span>
670
670
  </div>
671
671
  </div>
672
- <div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai">
672
+ <div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt">
673
673
  <div class="range-block-title" data-i18n="Temperature">
674
674
  Temperature
675
675
  </div>
@@ -682,7 +682,7 @@
682
682
  </div>
683
683
  </div>
684
684
  </div>
685
- <div class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq,mistralai">
685
+ <div class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt">
686
686
  <div class="range-block-title" data-i18n="Frequency Penalty">
687
687
  Frequency Penalty
688
688
  </div>
@@ -695,7 +695,7 @@
695
695
  </div>
696
696
  </div>
697
697
  </div>
698
- <div class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq,mistralai">
698
+ <div class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt">
699
699
  <div class="range-block-title" data-i18n="Presence Penalty">
700
700
  Presence Penalty
701
701
  </div>
@@ -721,7 +721,7 @@
721
721
  </div>
722
722
  </div>
723
723
  </div>
724
- <div class="range-block" data-source="openai,claude,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai">
724
+ <div class="range-block" data-source="openai,claude,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt">
725
725
  <div class="range-block-title" data-i18n="Top P">
726
726
  Top P
727
727
  </div>
@@ -958,7 +958,7 @@
958
958
  </div>
959
959
  </div>
960
960
  </div>
961
- <div class="range-block" data-source="openai,openrouter,mistralai,custom,cohere,groq">
961
+ <div class="range-block" data-source="openai,openrouter,mistralai,custom,cohere,groq,nanogpt">
962
962
  <div class="range-block-title justifyLeft" data-i18n="Seed">
963
963
  Seed
964
964
  </div>
@@ -1425,7 +1425,7 @@
1425
1425
  <input class="neo-range-slider" type="range" id="dry_allowed_length_textgenerationwebui" min="1" max="20" step="1" />
1426
1426
  <input class="neo-range-input" type="number" min="1" max="20" step="1" data-for="dry_allowed_length_textgenerationwebui" id="dry_allowed_length_counter_textgenerationwebui">
1427
1427
  </div>
1428
- <div class="alignItemsCenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0" data-tg-type="llamacpp, koboldcpp, tabby">
1428
+ <div class="alignItemsCenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0" data-tg-type="llamacpp, koboldcpp, tabby, aphrodite">
1429
1429
  <small data-i18n="Penalty Range">Penalty Range</small>
1430
1430
  <input class="neo-range-slider" type="range" id="dry_penalty_last_n_textgenerationwebui" min="0" max="8192" step="1" />
1431
1431
  <input class="neo-range-input" type="number" min="0" max="8192" step="1" data-for="dry_penalty_last_n_textgenerationwebui" id="dry_penalty_last_n_counter_textgenerationwebui">
@@ -2987,6 +2987,7 @@
2987
2987
  <optgroup label="Subversions">
2988
2988
  <option value="gemini-exp-1121">Gemini Experimental 2024-11-21</option>
2989
2989
  <option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option>
2990
+ <option value="gemini-exp-1206">Gemini Experimental 2024-12-06</option>
2990
2991
  <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option>
2991
2992
  <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experiment 2024-08-27</option>
2992
2993
  <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option>
@@ -4183,7 +4184,7 @@
4183
4184
  </label>
4184
4185
  <label for="show_swipe_num_all_messages" class="checkbox_label" title="Display swipe numbers for all messages, not just the last." data-i18n="[title]Display swipe numbers for all messages, not just the last.">
4185
4186
  <input id="show_swipe_num_all_messages" type="checkbox" />
4186
- <small data-i18n="Swipe # for All Messages">Swipe # for All Messages</small><i class="fa-solid fa-mobile-screen-button"></i>
4187
+ <small data-i18n="Swipe # for All Messages">Swipe # for All Messages</small>
4187
4188
  </label>
4188
4189
  <label for="hotswapEnabled" class="checkbox_label" title="In the Character Management panel, show quick selection buttons for favorited characters." data-i18n="[title]In the Character Management panel, show quick selection buttons for favorited characters">
4189
4190
  <input id="hotswapEnabled" type="checkbox" />
@@ -5,7 +5,8 @@
5
5
  "module": "ESNext",
6
6
  "moduleResolution": "node",
7
7
  "allowUmdGlobalAccess": true,
8
- "allowSyntheticDefaultImports": true
8
+ "allowSyntheticDefaultImports": true,
9
+ "strictBindCallApply": true
9
10
  },
10
11
  "exclude": [
11
12
  "**/node_modules/**",
package/public/script.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  default as libs,
14
14
  } from './lib.js';
15
15
 
16
- import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter } from './scripts/RossAscends-mods.js';
16
+ import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods } from './scripts/RossAscends-mods.js';
17
17
  import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';
18
18
  import {
19
19
  generateKoboldWithStreaming,
@@ -37,8 +37,6 @@ import {
37
37
  parseTabbyLogprobs,
38
38
  } from './scripts/textgen-settings.js';
39
39
 
40
- const { MANCER, TOGETHERAI, OOBA, VLLM, APHRODITE, TABBY, OLLAMA, INFERMATICAI, DREAMGEN, OPENROUTER, FEATHERLESS } = textgen_types;
41
-
42
40
  import {
43
41
  world_info,
44
42
  getWorldInfoPrompt,
@@ -67,9 +65,7 @@ import {
67
65
  getGroupChat,
68
66
  renameGroupMember,
69
67
  createNewGroupChat,
70
- getGroupPastChats,
71
68
  getGroupAvatar,
72
- openGroupChat,
73
69
  editGroup,
74
70
  deleteGroupChat,
75
71
  renameGroupChat,
@@ -98,7 +94,6 @@ import {
98
94
  resetMovableStyles,
99
95
  forceCharacterEditorTokenize,
100
96
  applyPowerUserSettings,
101
- switchSwipeNumAllMessages,
102
97
  } from './scripts/power-user.js';
103
98
 
104
99
  import {
@@ -174,8 +169,8 @@ import {
174
169
  } from './scripts/utils.js';
175
170
  import { debounce_timeout } from './scripts/constants.js';
176
171
 
177
- import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, initExtensions, loadExtensionSettings, renderExtensionTemplate, renderExtensionTemplateAsync, runGenerationInterceptors, saveMetadataDebounced, writeExtensionField } from './scripts/extensions.js';
178
- import { COMMENT_NAME_DEFAULT, executeSlashCommands, executeSlashCommandsOnChatInput, executeSlashCommandsWithOptions, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, registerSlashCommand, stopScriptExecution } from './scripts/slash-commands.js';
172
+ import { doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js';
173
+ import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js';
179
174
  import {
180
175
  tag_map,
181
176
  tags,
@@ -225,8 +220,8 @@ import {
225
220
  instruct_presets,
226
221
  selectContextPreset,
227
222
  } from './scripts/instruct-mode.js';
228
- import { initLocales, t, translate } from './scripts/i18n.js';
229
- import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, getTokenizerModel, initTokenizers, saveTokenCache, TOKENIZER_SUPPORTED_KEY } from './scripts/tokenizers.js';
223
+ import { initLocales, t } from './scripts/i18n.js';
224
+ import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, initTokenizers, saveTokenCache, TOKENIZER_SUPPORTED_KEY } from './scripts/tokenizers.js';
230
225
  import {
231
226
  user_avatar,
232
227
  getUserAvatars,
@@ -241,12 +236,12 @@ import { hideLoader, showLoader } from './scripts/loader.js';
241
236
  import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js';
242
237
  import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels } from './scripts/textgen-models.js';
243
238
  import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat } from './scripts/chats.js';
244
- import { initPresetManager } from './scripts/preset-manager.js';
245
- import { MacrosParser, evaluateMacros, getLastMessageId } from './scripts/macros.js';
239
+ import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';
240
+ import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';
246
241
  import { currentUser, setUserControls } from './scripts/user.js';
247
242
  import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
248
243
  import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
249
- import { initScrapers, ScraperManager } from './scripts/scrapers.js';
244
+ import { initScrapers } from './scripts/scrapers.js';
250
245
  import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
251
246
  import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
252
247
  import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
@@ -268,6 +263,13 @@ import { initServerHistory } from './scripts/server-history.js';
268
263
  import { initSettingsSearch } from './scripts/setting-search.js';
269
264
  import { initBulkEdit } from './scripts/bulk-edit.js';
270
265
  import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
266
+ import { getContext } from './scripts/st-context.js';
267
+
268
+ // API OBJECT FOR EXTERNAL WIRING
269
+ globalThis.SillyTavern = {
270
+ libs,
271
+ getContext,
272
+ };
271
273
 
272
274
  //exporting functions and vars for mods
273
275
  export {
@@ -427,10 +429,6 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => {
427
429
  }
428
430
  });
429
431
 
430
- // API OBJECT FOR EXTERNAL WIRING
431
- window['SillyTavern'] = {};
432
- window['SillyTavern'].libs = libs;
433
-
434
432
  // Event source init
435
433
  export const event_types = {
436
434
  APP_READY: 'app_ready',
@@ -536,7 +534,7 @@ let displayVersion = 'SillyTavern';
536
534
 
537
535
  let generatedPromptCache = '';
538
536
  let generation_started = new Date();
539
- /** @type {import('scripts/char-data.js').v1CharData[]} */
537
+ /** @type {import('./scripts/char-data.js').v1CharData[]} */
540
538
  export let characters = [];
541
539
  export let this_chid;
542
540
  let saveCharactersPage = 0;
@@ -812,7 +810,7 @@ export let menu_type = '';
812
810
  export let selected_button = ''; //which button pressed
813
811
 
814
812
  //create pole save
815
- let create_save = {
813
+ export let create_save = {
816
814
  name: '',
817
815
  description: '',
818
816
  creator_notes: '',
@@ -864,7 +862,7 @@ export let amount_gen = 80; //default max length of AI generated responses
864
862
  export let max_context = 2048;
865
863
 
866
864
  var swipes = true;
867
- let extension_prompts = {};
865
+ export let extension_prompts = {};
868
866
 
869
867
  export let main_api;// = "kobold";
870
868
  //novel settings
@@ -957,6 +955,7 @@ async function firstLoadInit() {
957
955
  initDynamicStyles();
958
956
  initTags();
959
957
  initBookmarks();
958
+ initMacros();
960
959
  await getUserAvatars(true, user_avatar);
961
960
  await getCharacters();
962
961
  await getBackgrounds();
@@ -1174,7 +1173,7 @@ async function getStatusTextgen() {
1174
1173
  return resultCheckStatus();
1175
1174
  }
1176
1175
 
1177
- if (textgen_settings.type == OOBA && textgen_settings.bypass_status_check) {
1176
+ if (textgen_settings.type == textgen_types.OOBA && textgen_settings.bypass_status_check) {
1178
1177
  setOnlineStatus('Status check bypassed');
1179
1178
  return resultCheckStatus();
1180
1179
  }
@@ -1192,34 +1191,34 @@ async function getStatusTextgen() {
1192
1191
 
1193
1192
  const data = await response.json();
1194
1193
 
1195
- if (textgen_settings.type === MANCER) {
1194
+ if (textgen_settings.type === textgen_types.MANCER) {
1196
1195
  loadMancerModels(data?.data);
1197
1196
  setOnlineStatus(textgen_settings.mancer_model);
1198
- } else if (textgen_settings.type === TOGETHERAI) {
1197
+ } else if (textgen_settings.type === textgen_types.TOGETHERAI) {
1199
1198
  loadTogetherAIModels(data?.data);
1200
1199
  setOnlineStatus(textgen_settings.togetherai_model);
1201
- } else if (textgen_settings.type === OLLAMA) {
1200
+ } else if (textgen_settings.type === textgen_types.OLLAMA) {
1202
1201
  loadOllamaModels(data?.data);
1203
1202
  setOnlineStatus(textgen_settings.ollama_model || 'Connected');
1204
- } else if (textgen_settings.type === INFERMATICAI) {
1203
+ } else if (textgen_settings.type === textgen_types.INFERMATICAI) {
1205
1204
  loadInfermaticAIModels(data?.data);
1206
1205
  setOnlineStatus(textgen_settings.infermaticai_model);
1207
- } else if (textgen_settings.type === DREAMGEN) {
1206
+ } else if (textgen_settings.type === textgen_types.DREAMGEN) {
1208
1207
  loadDreamGenModels(data?.data);
1209
1208
  setOnlineStatus(textgen_settings.dreamgen_model);
1210
- } else if (textgen_settings.type === OPENROUTER) {
1209
+ } else if (textgen_settings.type === textgen_types.OPENROUTER) {
1211
1210
  loadOpenRouterModels(data?.data);
1212
1211
  setOnlineStatus(textgen_settings.openrouter_model);
1213
- } else if (textgen_settings.type === VLLM) {
1212
+ } else if (textgen_settings.type === textgen_types.VLLM) {
1214
1213
  loadVllmModels(data?.data);
1215
1214
  setOnlineStatus(textgen_settings.vllm_model);
1216
- } else if (textgen_settings.type === APHRODITE) {
1215
+ } else if (textgen_settings.type === textgen_types.APHRODITE) {
1217
1216
  loadAphroditeModels(data?.data);
1218
1217
  setOnlineStatus(textgen_settings.aphrodite_model);
1219
- } else if (textgen_settings.type === FEATHERLESS) {
1218
+ } else if (textgen_settings.type === textgen_types.FEATHERLESS) {
1220
1219
  loadFeatherlessModels(data?.data);
1221
1220
  setOnlineStatus(textgen_settings.featherless_model);
1222
- } else if (textgen_settings.type === TABBY) {
1221
+ } else if (textgen_settings.type === textgen_types.TABBY) {
1223
1222
  loadTabbyModels(data?.data);
1224
1223
  setOnlineStatus(textgen_settings.tabby_model || data?.result);
1225
1224
  } else {
@@ -1636,7 +1635,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) {
1636
1635
  subEntities = entitiesFilter.applyFilters(subEntities, { clearScoreCache: false, tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED }, clearFuzzySearchCaches: false });
1637
1636
  }
1638
1637
  if (doSort) {
1639
- sortEntitiesList(subEntities);
1638
+ sortEntitiesList(subEntities, false);
1640
1639
  }
1641
1640
  entity.entities = subEntities;
1642
1641
  entity.hidden = subCount - subEntities.length;
@@ -1664,7 +1663,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) {
1664
1663
 
1665
1664
  // Sort before returning if requested
1666
1665
  if (doSort) {
1667
- sortEntitiesList(entities);
1666
+ sortEntitiesList(entities, false);
1668
1667
  }
1669
1668
  entitiesFilter.clearFuzzySearchCaches();
1670
1669
  return entities;
@@ -2606,15 +2605,18 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re
2606
2605
  };
2607
2606
  }
2608
2607
 
2609
- const getGroupValue = () => {
2608
+ const getGroupValue = (includeMuted) => {
2610
2609
  if (typeof _group === 'string') {
2611
2610
  return _group;
2612
2611
  }
2613
2612
 
2614
2613
  if (selected_group) {
2615
2614
  const members = groups.find(x => x.id === selected_group)?.members;
2615
+ /** @type {string[]} */
2616
+ const disabledMembers = groups.find(x => x.id === selected_group)?.disabled_members ?? [];
2617
+ const isMuted = x => includeMuted ? true : !disabledMembers.includes(x);
2616
2618
  const names = Array.isArray(members)
2617
- ? members.map(m => characters.find(c => c.avatar === m)?.name).filter(Boolean).join(', ')
2619
+ ? members.filter(isMuted).map(m => characters.find(c => c.avatar === m)?.name).filter(Boolean).join(', ')
2618
2620
  : '';
2619
2621
  return names;
2620
2622
  } else {
@@ -2638,7 +2640,8 @@ export function substituteParams(content, _name1, _name2, _original, _group, _re
2638
2640
  // Must be substituted last so that they're replaced inside {{description}}
2639
2641
  environment.user = _name1 ?? name1;
2640
2642
  environment.char = _name2 ?? name2;
2641
- environment.group = environment.charIfNotGroup = getGroupValue();
2643
+ environment.group = environment.charIfNotGroup = getGroupValue(true);
2644
+ environment.groupNotMuted = getGroupValue(false);
2642
2645
  environment.model = getGeneratingModel();
2643
2646
 
2644
2647
  if (additionalMacro && typeof additionalMacro === 'object') {
@@ -4493,6 +4496,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4493
4496
  instruction: main_api !== 'openai' && power_user.sysprompt.enabled ? substituteParams(power_user.prefer_character_prompt && system ? system : power_user.sysprompt.content) : '',
4494
4497
  userPersona: (power_user.persona_description_position == persona_description_positions.IN_PROMPT ? (persona || '') : ''),
4495
4498
  tokenizer: getFriendlyTokenizerName(main_api).tokenizerName || '',
4499
+ presetName: getPresetManager()?.getSelectedPresetName() || '',
4496
4500
  };
4497
4501
 
4498
4502
  //console.log(additionalPromptStuff);
@@ -5159,6 +5163,7 @@ export async function itemizedParams(itemizedPrompts, thisPromptSet, incomingMes
5159
5163
  dataBankVectorsStringTokens: await getTokenCountAsync(itemizedPrompts[thisPromptSet].dataBankVectorsString),
5160
5164
  modelUsed: chat[incomingMesId]?.extra?.model,
5161
5165
  apiUsed: chat[incomingMesId]?.extra?.api,
5166
+ presetName: itemizedPrompts[thisPromptSet].presetName || t`(Unknown)`,
5162
5167
  };
5163
5168
 
5164
5169
  const getFriendlyName = (value) => $(`#rm_api_block select option[value="${value}"]`).first().text() || value;
@@ -5535,7 +5540,7 @@ function extractMultiSwipes(data, type) {
5535
5540
  return swipes;
5536
5541
  }
5537
5542
 
5538
- if (main_api === 'openai' || (main_api === 'textgenerationwebui' && [MANCER, VLLM, APHRODITE, TABBY, INFERMATICAI].includes(textgen_settings.type))) {
5543
+ if (main_api === 'openai' || (main_api === 'textgenerationwebui' && [textgen_types.MANCER, textgen_types.VLLM, textgen_types.APHRODITE, textgen_types.TABBY, textgen_types.INFERMATICAI].includes(textgen_settings.type))) {
5539
5544
  if (!Array.isArray(data.choices)) {
5540
5545
  return swipes;
5541
5546
  }
@@ -5698,7 +5703,7 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc
5698
5703
  return getMessage;
5699
5704
  }
5700
5705
 
5701
- async function saveReply(type, getMessage, fromStreaming, title, swipes) {
5706
+ export async function saveReply(type, getMessage, fromStreaming, title, swipes) {
5702
5707
  if (type != 'append' && type != 'continue' && type != 'appendFinal' && chat.length && (chat[chat.length - 1]['swipe_id'] === undefined ||
5703
5708
  chat[chat.length - 1]['is_user'])) {
5704
5709
  type = 'normal';
@@ -7657,14 +7662,12 @@ export function showSwipeButtons() {
7657
7662
  //allows for writing individual swipe counters for past messages
7658
7663
  const lastSwipeCounter = $('.last_mes .swipes-counter');
7659
7664
  lastSwipeCounter.text(swipeCounterText).show();
7660
-
7661
- switchSwipeNumAllMessages();
7662
7665
  }
7663
7666
 
7664
7667
  export function hideSwipeButtons() {
7665
- $('#chat').find('.swipe_right').hide();
7666
- $('#chat').find('.last_mes .swipes-counter').hide();
7667
- $('#chat').find('.swipe_left').hide();
7668
+ chatElement.find('.swipe_right').hide();
7669
+ chatElement.find('.last_mes .swipes-counter').hide();
7670
+ chatElement.find('.swipe_left').hide();
7668
7671
  }
7669
7672
 
7670
7673
  /**
@@ -7751,25 +7754,31 @@ export async function saveChatConditional() {
7751
7754
  }
7752
7755
  }
7753
7756
 
7754
- async function importCharacterChat(formData) {
7755
- await jQuery.ajax({
7756
- type: 'POST',
7757
- url: '/api/chats/import',
7758
- data: formData,
7759
- beforeSend: function () {
7760
- },
7761
- cache: false,
7762
- contentType: false,
7763
- processData: false,
7764
- success: async function (data) {
7765
- if (data.res) {
7766
- await displayPastChats();
7767
- }
7768
- },
7769
- error: function () {
7770
- $('#create_button').removeAttr('disabled');
7771
- },
7757
+ /**
7758
+ * Saves the chat to the server.
7759
+ * @param {FormData} formData Form data to send to the server.
7760
+ * @param {EventTarget} eventTarget Event target to trigger the event on.
7761
+ */
7762
+ async function importCharacterChat(formData, eventTarget) {
7763
+ const headers = getRequestHeaders();
7764
+ delete headers['Content-Type'];
7765
+ const fetchResult = await fetch('/api/chats/import', {
7766
+ method: 'POST',
7767
+ body: formData,
7768
+ headers: headers,
7769
+ cache: 'no-cache',
7772
7770
  });
7771
+
7772
+ if (fetchResult.ok) {
7773
+ const data = await fetchResult.json();
7774
+ if (data.res) {
7775
+ await displayPastChats();
7776
+ }
7777
+ }
7778
+
7779
+ if (eventTarget instanceof HTMLInputElement) {
7780
+ eventTarget.value = '';
7781
+ }
7773
7782
  }
7774
7783
 
7775
7784
  function updateViewMessageIds(startFromZero = false) {
@@ -8224,102 +8233,6 @@ async function createOrEditCharacter(e) {
8224
8233
  }
8225
8234
  }
8226
8235
 
8227
- window['SillyTavern'].getContext = function () {
8228
- return {
8229
- chat: chat,
8230
- characters: characters,
8231
- groups: groups,
8232
- name1: name1,
8233
- name2: name2,
8234
- characterId: this_chid,
8235
- groupId: selected_group,
8236
- chatId: selected_group
8237
- ? groups.find(x => x.id == selected_group)?.chat_id
8238
- : (this_chid && characters[this_chid] && characters[this_chid].chat),
8239
- getCurrentChatId: getCurrentChatId,
8240
- getRequestHeaders: getRequestHeaders,
8241
- reloadCurrentChat: reloadCurrentChat,
8242
- renameChat: renameChat,
8243
- saveSettingsDebounced: saveSettingsDebounced,
8244
- onlineStatus: online_status,
8245
- maxContext: Number(max_context),
8246
- chatMetadata: chat_metadata,
8247
- streamingProcessor,
8248
- eventSource: eventSource,
8249
- eventTypes: event_types,
8250
- addOneMessage: addOneMessage,
8251
- generate: Generate,
8252
- sendStreamingRequest: sendStreamingRequest,
8253
- sendGenerationRequest: sendGenerationRequest,
8254
- stopGeneration: stopGeneration,
8255
- getTokenCount: getTokenCount,
8256
- extensionPrompts: extension_prompts,
8257
- setExtensionPrompt: setExtensionPrompt,
8258
- updateChatMetadata: updateChatMetadata,
8259
- saveChat: saveChatConditional,
8260
- openCharacterChat: openCharacterChat,
8261
- openGroupChat: openGroupChat,
8262
- saveMetadata: saveMetadata,
8263
- sendSystemMessage: sendSystemMessage,
8264
- activateSendButtons,
8265
- deactivateSendButtons,
8266
- saveReply,
8267
- substituteParams,
8268
- substituteParamsExtended,
8269
- SlashCommandParser,
8270
- SlashCommand,
8271
- SlashCommandArgument,
8272
- SlashCommandNamedArgument,
8273
- ARGUMENT_TYPE,
8274
- executeSlashCommandsWithOptions,
8275
- /** @deprecated Use SlashCommandParser.addCommandObject() instead */
8276
- registerSlashCommand: registerSlashCommand,
8277
- /** @deprecated Use executeSlashCommandWithOptions instead */
8278
- executeSlashCommands: executeSlashCommands,
8279
- timestampToMoment: timestampToMoment,
8280
- /** @deprecated Handlebars for extensions are no longer supported. */
8281
- registerHelper: () => { },
8282
- registerMacro: MacrosParser.registerMacro.bind(MacrosParser),
8283
- unregisterMacro: MacrosParser.unregisterMacro.bind(MacrosParser),
8284
- registerFunctionTool: ToolManager.registerFunctionTool.bind(ToolManager),
8285
- unregisterFunctionTool: ToolManager.unregisterFunctionTool.bind(ToolManager),
8286
- isToolCallingSupported: ToolManager.isToolCallingSupported.bind(ToolManager),
8287
- canPerformToolCalls: ToolManager.canPerformToolCalls.bind(ToolManager),
8288
- registerDebugFunction: registerDebugFunction,
8289
- /** @deprecated Use renderExtensionTemplateAsync instead. */
8290
- renderExtensionTemplate: renderExtensionTemplate,
8291
- renderExtensionTemplateAsync: renderExtensionTemplateAsync,
8292
- registerDataBankScraper: ScraperManager.registerDataBankScraper,
8293
- /** @deprecated Use callGenericPopup or Popup instead. */
8294
- callPopup: callPopup,
8295
- callGenericPopup: callGenericPopup,
8296
- showLoader: showLoader,
8297
- hideLoader: hideLoader,
8298
- mainApi: main_api,
8299
- extensionSettings: extension_settings,
8300
- ModuleWorkerWrapper: ModuleWorkerWrapper,
8301
- getTokenizerModel: getTokenizerModel,
8302
- generateQuietPrompt: generateQuietPrompt,
8303
- writeExtensionField: writeExtensionField,
8304
- getThumbnailUrl: getThumbnailUrl,
8305
- selectCharacterById: selectCharacterById,
8306
- messageFormatting: messageFormatting,
8307
- shouldSendOnEnter: shouldSendOnEnter,
8308
- isMobile: isMobile,
8309
- t: t,
8310
- translate: translate,
8311
- tags: tags,
8312
- tagMap: tag_map,
8313
- menuType: menu_type,
8314
- createCharacterData: create_save,
8315
- /** @deprecated Legacy snake-case naming, compatibility with old extensions */
8316
- event_types: event_types,
8317
- Popup: Popup,
8318
- POPUP_TYPE: POPUP_TYPE,
8319
- POPUP_RESULT: POPUP_RESULT,
8320
- };
8321
- };
8322
-
8323
8236
  /**
8324
8237
  * Formats a counter for a swipe view.
8325
8238
  * @param {number} current The current number of items.
@@ -10826,13 +10739,13 @@ jQuery(async function () {
10826
10739
  });
10827
10740
 
10828
10741
  $('#chat_import_file').on('change', async function (e) {
10829
- var file = e.target.files[0];
10742
+ const file = e.target.files[0];
10830
10743
 
10831
10744
  if (!file) {
10832
10745
  return;
10833
10746
  }
10834
10747
 
10835
- var ext = file.name.match(/\.(\w+)$/);
10748
+ const ext = file.name.match(/\.(\w+)$/);
10836
10749
  if (
10837
10750
  !ext ||
10838
10751
  (ext[1].toLowerCase() != 'json' && ext[1].toLowerCase() != 'jsonl')
@@ -10845,17 +10758,17 @@ jQuery(async function () {
10845
10758
  return;
10846
10759
  }
10847
10760
 
10848
- var format = ext[1].toLowerCase();
10761
+ const format = ext[1].toLowerCase();
10849
10762
  $('#chat_import_file_type').val(format);
10850
10763
 
10851
- var formData = new FormData($('#form_import_chat').get(0));
10764
+ const formData = new FormData($('#form_import_chat').get(0));
10852
10765
  formData.append('user_name', name1);
10853
10766
  $('#select_chat_div').html('');
10854
10767
 
10855
10768
  if (selected_group) {
10856
- await importGroupChat(formData);
10769
+ await importGroupChat(formData, e.originalEvent.target);
10857
10770
  } else {
10858
- await importCharacterChat(formData);
10771
+ await importCharacterChat(formData, e.originalEvent.target);
10859
10772
  }
10860
10773
  });
10861
10774
 
@@ -75,6 +75,7 @@
75
75
  * @property {string} [source_url] - The source URL associated with the character.
76
76
  * @property {{full_path: string}} [chub] - The Chub-specific data associated with the character.
77
77
  * @property {{source: string[]}} [risuai] - The RisuAI-specific data associated with the character.
78
+ * @property {{positive: string, negative: string}} [sd_character_prompt] - SD-specific data associated with the character.
78
79
  */
79
80
 
80
81
  /**
@@ -62,6 +62,7 @@
62
62
  <option data-type="google" value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option>
63
63
  <option data-type="google" value="gemini-exp-1114">gemini-exp-1114</option>
64
64
  <option data-type="google" value="gemini-exp-1121">gemini-exp-1121</option>
65
+ <option data-type="google" value="gemini-exp-1206">gemini-exp-1206</option>
65
66
  <option data-type="google" value="gemini-1.5-pro">gemini-1.5-pro</option>
66
67
  <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option>
67
68
  <option data-type="google" value="gemini-1.5-pro-001">gemini-1.5-pro-001</option>