Add types for SillyTavern.getContext

77841dbc2169003bc78970958dc9c68fe55a1a08

Cohee <18619528+Cohee1207@users.noreply.github.com>

7 files changed, +228 -146Ignore whitespace
.eslintrc.cjs+1 -0
@@ -54,6 +54,7 @@ module.exports = {
5454 },
5555 // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined
5656 globals: {
57+ globalThis: 'readonly',
5758 ePub: 'readonly',
5859 pdfjsLib: 'readonly',
5960 toastr: 'readonly',
public/global.d.ts+2 -1
@@ -1,4 +1,5 @@
11import libs from './lib';
2+import getContext from './scripts/st-context';
23
34// Global namespace modules
45declare var ai;
@@ -6,7 +7,7 @@ declare var pdfjsLib;
67declare var ePub;
78
89declare var SillyTavern: {
910 getContext(): anytypeof getContext;
1011 llm: any;
1112 libs: typeof libs;
1213};
public/script.js+27 -124
@@ -13,7 +13,7 @@ import {
1313 default as libs,
1414} from './lib.js';
1515
1616import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter } from './scripts/RossAscends-mods.js';
1717import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';
1818import {
1919 generateKoboldWithStreaming,
@@ -37,8 +37,6 @@ import {
3737 parseTabbyLogprobs,
3838} from './scripts/textgen-settings.js';
3939
40-const { MANCER, TOGETHERAI, OOBA, VLLM, APHRODITE, TABBY, OLLAMA, INFERMATICAI, DREAMGEN, OPENROUTER, FEATHERLESS } = textgen_types;
41-
4240import {
4341 world_info,
4442 getWorldInfoPrompt,
@@ -67,9 +65,7 @@ import {
6765 getGroupChat,
6866 renameGroupMember,
6967 createNewGroupChat,
70- getGroupPastChats,
7168 getGroupAvatar,
72- openGroupChat,
7369 editGroup,
7470 deleteGroupChat,
7571 renameGroupChat,
@@ -174,8 +170,8 @@ import {
174170} from './scripts/utils.js';
175171import { debounce_timeout } from './scripts/constants.js';
176172
177173import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, initExtensions, loadExtensionSettings, renderExtensionTemplate, renderExtensionTemplateAsync, runGenerationInterceptors, saveMetadataDebounced, writeExtensionField } from './scripts/extensions.js';
178174import { COMMENT_NAME_DEFAULT, executeSlashCommands, executeSlashCommandsOnChatInput, executeSlashCommandsWithOptions, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, registerSlashCommand, stopScriptExecution } from './scripts/slash-commands.js';
179175import {
180176 tag_map,
181177 tags,
@@ -242,11 +238,11 @@ import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay
242238import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels } from './scripts/textgen-models.js';
243239import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat } from './scripts/chats.js';
244240import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';
245241import { MacrosParser, evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';
246242import { currentUser, setUserControls } from './scripts/user.js';
247243import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
248244import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
249245import { initScrapers, ScraperManager } from './scripts/scrapers.js';
250246import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
251247import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
252248import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
@@ -268,6 +264,13 @@ import { initServerHistory } from './scripts/server-history.js';
268264import { initSettingsSearch } from './scripts/setting-search.js';
269265import { initBulkEdit } from './scripts/bulk-edit.js';
270266import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
267+import { getContext } from './scripts/st-context.js';
268+
269+// API OBJECT FOR EXTERNAL WIRING
270+globalThis.SillyTavern = {
271+ libs,
272+ getContext,
273+};
271274
272275//exporting functions and vars for mods
273276export {
@@ -427,10 +430,6 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => {
427430 }
428431});
429432
430-// API OBJECT FOR EXTERNAL WIRING
431-window['SillyTavern'] = {};
432-window['SillyTavern'].libs = libs;
433-
434433// Event source init
435434export const event_types = {
436435 APP_READY: 'app_ready',
@@ -812,7 +811,7 @@ export let menu_type = '';
812811export let selected_button = ''; //which button pressed
813812
814813//create pole save
815814export let create_save = {
816815 name: '',
817816 description: '',
818817 creator_notes: '',
@@ -864,7 +863,7 @@ export let amount_gen = 80; //default max length of AI generated responses
864863export let max_context = 2048;
865864
866865var swipes = true;
867866export let extension_prompts = {};
868867
869868export let main_api;// = "kobold";
870869//novel settings
@@ -1175,7 +1174,7 @@ async function getStatusTextgen() {
11751174 return resultCheckStatus();
11761175 }
11771176
11781177 if (textgen_settings.type == textgen_types.OOBA && textgen_settings.bypass_status_check) {
11791178 setOnlineStatus('Status check bypassed');
11801179 return resultCheckStatus();
11811180 }
@@ -1193,34 +1192,34 @@ async function getStatusTextgen() {
11931192
11941193 const data = await response.json();
11951194
11961195 if (textgen_settings.type === textgen_types.MANCER) {
11971196 loadMancerModels(data?.data);
11981197 setOnlineStatus(textgen_settings.mancer_model);
11991198 } else if (textgen_settings.type === textgen_types.TOGETHERAI) {
12001199 loadTogetherAIModels(data?.data);
12011200 setOnlineStatus(textgen_settings.togetherai_model);
12021201 } else if (textgen_settings.type === textgen_types.OLLAMA) {
12031202 loadOllamaModels(data?.data);
12041203 setOnlineStatus(textgen_settings.ollama_model || 'Connected');
12051204 } else if (textgen_settings.type === textgen_types.INFERMATICAI) {
12061205 loadInfermaticAIModels(data?.data);
12071206 setOnlineStatus(textgen_settings.infermaticai_model);
12081207 } else if (textgen_settings.type === textgen_types.DREAMGEN) {
12091208 loadDreamGenModels(data?.data);
12101209 setOnlineStatus(textgen_settings.dreamgen_model);
12111210 } else if (textgen_settings.type === textgen_types.OPENROUTER) {
12121211 loadOpenRouterModels(data?.data);
12131212 setOnlineStatus(textgen_settings.openrouter_model);
12141213 } else if (textgen_settings.type === textgen_types.VLLM) {
12151214 loadVllmModels(data?.data);
12161215 setOnlineStatus(textgen_settings.vllm_model);
12171216 } else if (textgen_settings.type === textgen_types.APHRODITE) {
12181217 loadAphroditeModels(data?.data);
12191218 setOnlineStatus(textgen_settings.aphrodite_model);
12201219 } else if (textgen_settings.type === textgen_types.FEATHERLESS) {
12211220 loadFeatherlessModels(data?.data);
12221221 setOnlineStatus(textgen_settings.featherless_model);
12231222 } else if (textgen_settings.type === textgen_types.TABBY) {
12241223 loadTabbyModels(data?.data);
12251224 setOnlineStatus(textgen_settings.tabby_model || data?.result);
12261225 } else {
@@ -5542,7 +5541,7 @@ function extractMultiSwipes(data, type) {
55425541 return swipes;
55435542 }
55445543
55455544 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))) {
55465545 if (!Array.isArray(data.choices)) {
55475546 return swipes;
55485547 }
@@ -5705,7 +5704,7 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc
57055704 return getMessage;
57065705}
57075706
57085707export async function saveReply(type, getMessage, fromStreaming, title, swipes) {
57095708 if (type != 'append' && type != 'continue' && type != 'appendFinal' && chat.length && (chat[chat.length - 1]['swipe_id'] === undefined ||
57105709 chat[chat.length - 1]['is_user'])) {
57115710 type = 'normal';
@@ -8237,102 +8236,6 @@ async function createOrEditCharacter(e) {
82378236 }
82388237}
82398238
8240-window['SillyTavern'].getContext = function () {
8241- return {
8242- chat: chat,
8243- characters: characters,
8244- groups: groups,
8245- name1: name1,
8246- name2: name2,
8247- characterId: this_chid,
8248- groupId: selected_group,
8249- chatId: selected_group
8250- ? groups.find(x => x.id == selected_group)?.chat_id
8251- : (this_chid && characters[this_chid] && characters[this_chid].chat),
8252- getCurrentChatId: getCurrentChatId,
8253- getRequestHeaders: getRequestHeaders,
8254- reloadCurrentChat: reloadCurrentChat,
8255- renameChat: renameChat,
8256- saveSettingsDebounced: saveSettingsDebounced,
8257- onlineStatus: online_status,
8258- maxContext: Number(max_context),
8259- chatMetadata: chat_metadata,
8260- streamingProcessor,
8261- eventSource: eventSource,
8262- eventTypes: event_types,
8263- addOneMessage: addOneMessage,
8264- generate: Generate,
8265- sendStreamingRequest: sendStreamingRequest,
8266- sendGenerationRequest: sendGenerationRequest,
8267- stopGeneration: stopGeneration,
8268- getTokenCount: getTokenCount,
8269- extensionPrompts: extension_prompts,
8270- setExtensionPrompt: setExtensionPrompt,
8271- updateChatMetadata: updateChatMetadata,
8272- saveChat: saveChatConditional,
8273- openCharacterChat: openCharacterChat,
8274- openGroupChat: openGroupChat,
8275- saveMetadata: saveMetadata,
8276- sendSystemMessage: sendSystemMessage,
8277- activateSendButtons,
8278- deactivateSendButtons,
8279- saveReply,
8280- substituteParams,
8281- substituteParamsExtended,
8282- SlashCommandParser,
8283- SlashCommand,
8284- SlashCommandArgument,
8285- SlashCommandNamedArgument,
8286- ARGUMENT_TYPE,
8287- executeSlashCommandsWithOptions,
8288- /** @deprecated Use SlashCommandParser.addCommandObject() instead */
8289- registerSlashCommand: registerSlashCommand,
8290- /** @deprecated Use executeSlashCommandWithOptions instead */
8291- executeSlashCommands: executeSlashCommands,
8292- timestampToMoment: timestampToMoment,
8293- /** @deprecated Handlebars for extensions are no longer supported. */
8294- registerHelper: () => { },
8295- registerMacro: MacrosParser.registerMacro.bind(MacrosParser),
8296- unregisterMacro: MacrosParser.unregisterMacro.bind(MacrosParser),
8297- registerFunctionTool: ToolManager.registerFunctionTool.bind(ToolManager),
8298- unregisterFunctionTool: ToolManager.unregisterFunctionTool.bind(ToolManager),
8299- isToolCallingSupported: ToolManager.isToolCallingSupported.bind(ToolManager),
8300- canPerformToolCalls: ToolManager.canPerformToolCalls.bind(ToolManager),
8301- registerDebugFunction: registerDebugFunction,
8302- /** @deprecated Use renderExtensionTemplateAsync instead. */
8303- renderExtensionTemplate: renderExtensionTemplate,
8304- renderExtensionTemplateAsync: renderExtensionTemplateAsync,
8305- registerDataBankScraper: ScraperManager.registerDataBankScraper,
8306- /** @deprecated Use callGenericPopup or Popup instead. */
8307- callPopup: callPopup,
8308- callGenericPopup: callGenericPopup,
8309- showLoader: showLoader,
8310- hideLoader: hideLoader,
8311- mainApi: main_api,
8312- extensionSettings: extension_settings,
8313- ModuleWorkerWrapper: ModuleWorkerWrapper,
8314- getTokenizerModel: getTokenizerModel,
8315- generateQuietPrompt: generateQuietPrompt,
8316- writeExtensionField: writeExtensionField,
8317- getThumbnailUrl: getThumbnailUrl,
8318- selectCharacterById: selectCharacterById,
8319- messageFormatting: messageFormatting,
8320- shouldSendOnEnter: shouldSendOnEnter,
8321- isMobile: isMobile,
8322- t: t,
8323- translate: translate,
8324- tags: tags,
8325- tagMap: tag_map,
8326- menuType: menu_type,
8327- createCharacterData: create_save,
8328- /** @deprecated Legacy snake-case naming, compatibility with old extensions */
8329- event_types: event_types,
8330- Popup: Popup,
8331- POPUP_TYPE: POPUP_TYPE,
8332- POPUP_RESULT: POPUP_RESULT,
8333- };
8334-};
8335-
83368239/**
83378240 * Formats a counter for a swipe view.
83388241 * @param {number} current The current number of items.
public/scripts/extensions.js+1 -1
@@ -5,6 +5,7 @@ import { showLoader } from './loader.js';
55import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
66import { renderTemplate, renderTemplateAsync } from './templates.js';
77import { isSubsetOf, setValueByPath } from './utils.js';
8+import { getContext } from './st-context.js';
89export {
910 getContext,
1011 getApiUrl,
@@ -174,7 +175,6 @@ const extension_settings = {
174175let modules = [];
175176let activeExtensions = new Set();
176177
177-const getContext = () => window['SillyTavern'].getContext();
178178const getApiUrl = () => extension_settings.apiUrl;
179179let connectedToApi = false;
180180
public/scripts/st-context.js+170 -0
@@ -0,0 +1,170 @@
1+import {
2+ activateSendButtons,
3+ addOneMessage,
4+ callPopup,
5+ characters,
6+ chat,
7+ chat_metadata,
8+ create_save,
9+ deactivateSendButtons,
10+ event_types,
11+ eventSource,
12+ extension_prompts,
13+ Generate,
14+ generateQuietPrompt,
15+ getCurrentChatId,
16+ getRequestHeaders,
17+ getThumbnailUrl,
18+ main_api,
19+ max_context,
20+ menu_type,
21+ messageFormatting,
22+ name1,
23+ name2,
24+ online_status,
25+ openCharacterChat,
26+ reloadCurrentChat,
27+ renameChat,
28+ saveChatConditional,
29+ saveMetadata,
30+ saveReply,
31+ saveSettingsDebounced,
32+ selectCharacterById,
33+ sendGenerationRequest,
34+ sendStreamingRequest,
35+ sendSystemMessage,
36+ setExtensionPrompt,
37+ stopGeneration,
38+ streamingProcessor,
39+ substituteParams,
40+ substituteParamsExtended,
41+ this_chid,
42+ updateChatMetadata,
43+} from '../script.js';
44+import {
45+ extension_settings,
46+ ModuleWorkerWrapper,
47+ renderExtensionTemplate,
48+ renderExtensionTemplateAsync,
49+ writeExtensionField,
50+} from './extensions.js';
51+import { groups, openGroupChat, selected_group } from './group-chats.js';
52+import { t, translate } from './i18n.js';
53+import { hideLoader, showLoader } from './loader.js';
54+import { MacrosParser } from './macros.js';
55+import { oai_settings } from './openai.js';
56+import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
57+import { registerDebugFunction } from './power-user.js';
58+import { isMobile, shouldSendOnEnter } from './RossAscends-mods.js';
59+import { ScraperManager } from './scrapers.js';
60+import { executeSlashCommands, executeSlashCommandsWithOptions, registerSlashCommand } from './slash-commands.js';
61+import { SlashCommand } from './slash-commands/SlashCommand.js';
62+import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js';
63+import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
64+import { tag_map, tags } from './tags.js';
65+import { textgenerationwebui_settings } from './textgen-settings.js';
66+import { getTokenCount, getTokenCountAsync, getTokenizerModel } from './tokenizers.js';
67+import { ToolManager } from './tool-calling.js';
68+import { timestampToMoment } from './utils.js';
69+
70+export function getContext() {
71+ return {
72+ chatCompletionSettings: oai_settings,
73+ textCompletionSettings: textgenerationwebui_settings,
74+ chat,
75+ characters,
76+ groups,
77+ name1,
78+ name2,
79+ characterId: this_chid,
80+ groupId: selected_group,
81+ chatId: selected_group
82+ ? groups.find(x => x.id == selected_group)?.chat_id
83+ : (this_chid && characters[this_chid] && characters[this_chid].chat),
84+ getCurrentChatId,
85+ getRequestHeaders,
86+ reloadCurrentChat,
87+ renameChat,
88+ saveSettingsDebounced,
89+ onlineStatus: online_status,
90+ maxContext: Number(max_context),
91+ chatMetadata: chat_metadata,
92+ streamingProcessor,
93+ eventSource,
94+ eventTypes: event_types,
95+ addOneMessage,
96+ generate: Generate,
97+ sendStreamingRequest,
98+ sendGenerationRequest,
99+ stopGeneration,
100+ /** @deprecated Use getTokenCountAsync instead */
101+ getTokenCount,
102+ getTokenCountAsync,
103+ extensionPrompts: extension_prompts,
104+ setExtensionPrompt: setExtensionPrompt,
105+ updateChatMetadata: updateChatMetadata,
106+ saveChat: saveChatConditional,
107+ openCharacterChat,
108+ openGroupChat,
109+ saveMetadata,
110+ sendSystemMessage,
111+ activateSendButtons,
112+ deactivateSendButtons,
113+ saveReply,
114+ substituteParams,
115+ substituteParamsExtended,
116+ SlashCommandParser,
117+ SlashCommand,
118+ SlashCommandArgument,
119+ SlashCommandNamedArgument,
120+ ARGUMENT_TYPE,
121+ executeSlashCommandsWithOptions,
122+ /** @deprecated Use SlashCommandParser.addCommandObject() instead */
123+ registerSlashCommand,
124+ /** @deprecated Use executeSlashCommandWithOptions instead */
125+ executeSlashCommands,
126+ timestampToMoment,
127+ /** @deprecated Handlebars for extensions are no longer supported. */
128+ registerHelper: () => { },
129+ registerMacro: MacrosParser.registerMacro.bind(MacrosParser),
130+ unregisterMacro: MacrosParser.unregisterMacro.bind(MacrosParser),
131+ registerFunctionTool: ToolManager.registerFunctionTool.bind(ToolManager),
132+ unregisterFunctionTool: ToolManager.unregisterFunctionTool.bind(ToolManager),
133+ isToolCallingSupported: ToolManager.isToolCallingSupported.bind(ToolManager),
134+ canPerformToolCalls: ToolManager.canPerformToolCalls.bind(ToolManager),
135+ registerDebugFunction: registerDebugFunction,
136+ /** @deprecated Use renderExtensionTemplateAsync instead. */
137+ renderExtensionTemplate: renderExtensionTemplate,
138+ renderExtensionTemplateAsync: renderExtensionTemplateAsync,
139+ registerDataBankScraper: ScraperManager.registerDataBankScraper,
140+ /** @deprecated Use callGenericPopup or Popup instead. */
141+ callPopup,
142+ callGenericPopup,
143+ showLoader,
144+ hideLoader,
145+ mainApi: main_api,
146+ extensionSettings: extension_settings,
147+ ModuleWorkerWrapper,
148+ getTokenizerModel,
149+ generateQuietPrompt,
150+ writeExtensionField,
151+ getThumbnailUrl,
152+ selectCharacterById,
153+ messageFormatting,
154+ shouldSendOnEnter,
155+ isMobile,
156+ t,
157+ translate,
158+ tags,
159+ tagMap: tag_map,
160+ menuType: menu_type,
161+ createCharacterData: create_save,
162+ /** @deprecated Legacy snake-case naming, compatibility with old extensions */
163+ event_types: event_types,
164+ Popup: Popup,
165+ POPUP_TYPE,
166+ POPUP_RESULT,
167+ };
168+}
169+
170+export default getContext;
public/scripts/textgen-settings.js+7 -10
@@ -18,13 +18,6 @@ import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer }
1818import { ENCODE_TOKENIZERS, TEXTGEN_TOKENIZERS, getTextTokens, tokenizers } from './tokenizers.js';
1919import { getSortableDelay, onlyUnique } from './utils.js';
2020
21-export {
22- settings as textgenerationwebui_settings,
23- loadTextGenSettings,
24- generateTextGenWithStreaming,
25- formatTextGenURL,
26-};
27-
2821export const textgen_types = {
2922 OOBA: 'ooba',
3023 MANCER: 'mancer',
@@ -197,6 +190,10 @@ const settings = {
197190 featherless_model: '',
198191};
199192
193+export {
194+ settings as textgenerationwebui_settings,
195+};
196+
200197export let textgenerationwebui_banned_in_macros = [];
201198
202199export let textgenerationwebui_presets = [];
@@ -327,7 +324,7 @@ async function selectPreset(name) {
327324 saveSettingsDebounced();
328325}
329326
330327export function formatTextGenURL(value) {
331328 try {
332329 const noFormatTypes = [MANCER, TOGETHERAI, INFERMATICAI, DREAMGEN, OPENROUTER];
333330 if (noFormatTypes.includes(settings.type)) {
@@ -465,7 +462,7 @@ function calculateLogitBias() {
465462 return result;
466463}
467464
468465export function loadTextGenSettings(data, loadedSettings) {
469466 textgenerationwebui_presets = convertPresets(data.textgenerationwebui_presets);
470467 textgenerationwebui_preset_names = data.textgenerationwebui_preset_names ?? [];
471468 Object.assign(settings, loadedSettings.textgenerationwebui_settings ?? {});
@@ -889,7 +886,7 @@ function setSettingByName(setting, value, trigger) {
889886 * @returns {Promise<(function(): AsyncGenerator<{swipes: [], text: string, toolCalls: [], logprobs: {token: string, topLogprobs: Candidate[]}|null}, void, *>)|*>}
890887 * @throws {Error} - If the response status is not OK, or from within the generator
891888 */
892889export async function generateTextGenWithStreaming(generate_data, signal) {
893890 generate_data.stream = true;
894891
895892 const response = await fetch('/api/backends/text-completions/generate', {
public/scripts/tokenizers.js+20 -10
@@ -8,8 +8,6 @@ import { kai_flags } from './kai-settings.js';
88import { textgen_types, textgenerationwebui_settings as textgen_settings, getTextGenServer, getTextGenModel } from './textgen-settings.js';
99import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer, openRouterModels } from './textgen-models.js';
1010
11-const { OOBA, TABBY, KOBOLDCPP, VLLM, APHRODITE, LLAMACPP, OPENROUTER, DREAMGEN } = textgen_types;
12-
1311export const CHARACTERS_PER_TOKEN_RATIO = 3.35;
1412export const TOKENIZER_WARNING_KEY = 'tokenizationWarningShown';
1513export const TOKENIZER_SUPPORTED_KEY = 'tokenizationSupported';
@@ -52,8 +50,12 @@ export const ENCODE_TOKENIZERS = [
5250 //tokenizers.NERD2,
5351];
5452
55-// A list of Text Completion sources that support remote tokenization.
53+/**
56-export const TEXTGEN_TOKENIZERS = [OOBA, TABBY, KOBOLDCPP, LLAMACPP, VLLM, APHRODITE];
54+ * A list of Text Completion sources that support remote tokenization.
55+ * Populated in initTokenziers due to circular dependencies.
56+ * @type {string[]}
57+ */
58+export const TEXTGEN_TOKENIZERS = [];
5759
5860const TOKENIZER_URLS = {
5961 [tokenizers.GPT2]: {
@@ -287,7 +289,7 @@ export function getTokenizerBestMatch(forApi) {
287289 const hasTokenizerError = sessionStorage.getItem(TOKENIZER_WARNING_KEY);
288290 const hasValidEndpoint = sessionStorage.getItem(TOKENIZER_SUPPORTED_KEY);
289291 const isConnected = online_status !== 'no_connection';
290292 const isTokenizerSupported = TEXTGEN_TOKENIZERS.includes(textgen_settings.type) && (textgen_settings.type !== textgen_types.OOBA || hasValidEndpoint);
291293
292294 if (!hasTokenizerError && isConnected) {
293295 if (forApi === 'kobold' && kai_flags.can_use_tokenization) {
@@ -297,10 +299,10 @@ export function getTokenizerBestMatch(forApi) {
297299 if (forApi === 'textgenerationwebui' && isTokenizerSupported) {
298300 return tokenizers.API_TEXTGENERATIONWEBUI;
299301 }
300302 if (forApi === 'textgenerationwebui' && textgen_settings.type === textgen_types.OPENROUTER) {
301303 return getCurrentOpenRouterModelTokenizer();
302304 }
303305 if (forApi === 'textgenerationwebui' && textgen_settings.type === textgen_types.DREAMGEN) {
304306 return getCurrentDreamGenModelTokenizer();
305307 }
306308 }
@@ -576,7 +578,7 @@ export function getTokenizerModel() {
576578
577579 // And for OpenRouter (if not a site model, then it's impossible to determine the tokenizer)
578580 if (main_api == 'openai' && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER && oai_settings.openrouter_model ||
579581 main_api == 'textgenerationwebui' && textgen_settings.type === textgen_types.OPENROUTER && textgen_settings.openrouter_model) {
580582 const model = main_api == 'openai'
581583 ? model_list.find(x => x.id === oai_settings.openrouter_model)
582584 : openRouterModels.find(x => x.id === textgen_settings.openrouter_model);
@@ -652,7 +654,7 @@ export function getTokenizerModel() {
652654 return oai_settings.custom_model;
653655 }
654656
655657 if (oai_settings.chat_completion_source === chat_completion_sources.PERPLEXITY) {
656658 if (oai_settings.perplexity_model.includes('llama-3') || oai_settings.perplexity_model.includes('llama3')) {
657659 return llama3Tokenizer;
658660 }
@@ -680,7 +682,7 @@ export function getTokenizerModel() {
680682 return yiTokenizer;
681683 }
682684
683685 if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) {
684686 if (oai_settings.blockentropy_model.includes('llama3')) {
685687 return llama3Tokenizer;
686688 }
@@ -1121,6 +1123,14 @@ export function decodeTextTokens(tokenizerType, ids) {
11211123}
11221124
11231125export async function initTokenizers() {
1126+ TEXTGEN_TOKENIZERS.push(
1127+ textgen_types.OOBA,
1128+ textgen_types.TABBY,
1129+ textgen_types.KOBOLDCPP,
1130+ textgen_types.LLAMACPP,
1131+ textgen_types.VLLM,
1132+ textgen_types.APHRODITE,
1133+ );
11241134 await loadTokenCache();
11251135 registerDebugFunction('resetTokenCache', 'Reset token cache', 'Purges the calculated token counts. Use this if you want to force a full re-tokenization of all chats or suspect the token counts are wrong.', resetTokenCache);
11261136}