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 = {
54 },54 },
55 // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined55 // These scripts are loaded in HTML; tell ESLint not to complain about them being undefined
56 globals: {56 globals: {
57 globalThis: 'readonly',
57 ePub: 'readonly',58 ePub: 'readonly',
58 pdfjsLib: 'readonly',59 pdfjsLib: 'readonly',
59 toastr: 'readonly',60 toastr: 'readonly',
public/global.d.ts+2 -1
@@ -1,4 +1,5 @@
1import libs from './lib';1import libs from './lib';
2import getContext from './scripts/st-context';
23
3// Global namespace modules4// Global namespace modules
4declare var ai;5declare var ai;
@@ -6,7 +7,7 @@ declare var pdfjsLib;
6declare var ePub;7declare var ePub;
78
8declare var SillyTavern: {9declare var SillyTavern: {
9 getContext(): any;10 getContext(): typeof getContext;
10 llm: any;11 llm: any;
11 libs: typeof libs;12 libs: typeof libs;
12};13};
public/script.js+27 -124
@@ -13,7 +13,7 @@ import {
13 default as libs,13 default as libs,
14} from './lib.js';14} from './lib.js';
1515
16import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter } from './scripts/RossAscends-mods.js';16import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods } from './scripts/RossAscends-mods.js';
17import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';17import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js';
18import {18import {
19 generateKoboldWithStreaming,19 generateKoboldWithStreaming,
@@ -37,8 +37,6 @@ import {
37 parseTabbyLogprobs,37 parseTabbyLogprobs,
38} from './scripts/textgen-settings.js';38} from './scripts/textgen-settings.js';
3939
40const { MANCER, TOGETHERAI, OOBA, VLLM, APHRODITE, TABBY, OLLAMA, INFERMATICAI, DREAMGEN, OPENROUTER, FEATHERLESS } = textgen_types;
41
42import {40import {
43 world_info,41 world_info,
44 getWorldInfoPrompt,42 getWorldInfoPrompt,
@@ -67,9 +65,7 @@ import {
67 getGroupChat,65 getGroupChat,
68 renameGroupMember,66 renameGroupMember,
69 createNewGroupChat,67 createNewGroupChat,
70 getGroupPastChats,
71 getGroupAvatar,68 getGroupAvatar,
72 openGroupChat,
73 editGroup,69 editGroup,
74 deleteGroupChat,70 deleteGroupChat,
75 renameGroupChat,71 renameGroupChat,
@@ -174,8 +170,8 @@ import {
174} from './scripts/utils.js';170} from './scripts/utils.js';
175import { debounce_timeout } from './scripts/constants.js';171import { debounce_timeout } from './scripts/constants.js';
176172
177import { ModuleWorkerWrapper, doDailyExtensionUpdatesCheck, extension_settings, getContext, initExtensions, loadExtensionSettings, renderExtensionTemplate, renderExtensionTemplateAsync, runGenerationInterceptors, saveMetadataDebounced, writeExtensionField } from './scripts/extensions.js';173import { doDailyExtensionUpdatesCheck, extension_settings, initExtensions, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from './scripts/extensions.js';
178import { COMMENT_NAME_DEFAULT, executeSlashCommands, executeSlashCommandsOnChatInput, executeSlashCommandsWithOptions, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, registerSlashCommand, stopScriptExecution } from './scripts/slash-commands.js';174import { COMMENT_NAME_DEFAULT, executeSlashCommandsOnChatInput, getSlashCommandsHelp, initDefaultSlashCommands, isExecutingCommandsFromChatInput, pauseScriptExecution, processChatSlashCommands, stopScriptExecution } from './scripts/slash-commands.js';
179import {175import {
180 tag_map,176 tag_map,
181 tags,177 tags,
@@ -242,11 +238,11 @@ import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay
242import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels } from './scripts/textgen-models.js';238import { loadFeatherlessModels, loadMancerModels, loadOllamaModels, loadTogetherAIModels, loadInfermaticAIModels, loadOpenRouterModels, loadVllmModels, loadAphroditeModels, loadDreamGenModels, initTextGenModels, loadTabbyModels } from './scripts/textgen-models.js';
243import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat } from './scripts/chats.js';239import { appendFileContent, hasPendingFileAttachment, populateFileAttachment, decodeStyleTags, encodeStyleTags, isExternalMediaAllowed, getCurrentEntityId, preserveNeutralChat, restoreNeutralChat } from './scripts/chats.js';
244import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';240import { getPresetManager, initPresetManager } from './scripts/preset-manager.js';
245import { MacrosParser, evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';241import { evaluateMacros, getLastMessageId, initMacros } from './scripts/macros.js';
246import { currentUser, setUserControls } from './scripts/user.js';242import { currentUser, setUserControls } from './scripts/user.js';
247import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';243import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
248import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';244import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
249import { initScrapers, ScraperManager } from './scripts/scrapers.js';245import { initScrapers } from './scripts/scrapers.js';
250import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';246import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
251import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';247import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
252import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';248import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
@@ -268,6 +264,13 @@ import { initServerHistory } from './scripts/server-history.js';
268import { initSettingsSearch } from './scripts/setting-search.js';264import { initSettingsSearch } from './scripts/setting-search.js';
269import { initBulkEdit } from './scripts/bulk-edit.js';265import { initBulkEdit } from './scripts/bulk-edit.js';
270import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';266import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js';
267import { getContext } from './scripts/st-context.js';
268
269// API OBJECT FOR EXTERNAL WIRING
270globalThis.SillyTavern = {
271 libs,
272 getContext,
273};
271274
272//exporting functions and vars for mods275//exporting functions and vars for mods
273export {276export {
@@ -427,10 +430,6 @@ DOMPurify.addHook('uponSanitizeElement', (node, _, config) => {
427 }430 }
428});431});
429432
430// API OBJECT FOR EXTERNAL WIRING
431window['SillyTavern'] = {};
432window['SillyTavern'].libs = libs;
433
434// Event source init433// Event source init
435export const event_types = {434export const event_types = {
436 APP_READY: 'app_ready',435 APP_READY: 'app_ready',
@@ -812,7 +811,7 @@ export let menu_type = '';
812export let selected_button = ''; //which button pressed811export let selected_button = ''; //which button pressed
813812
814//create pole save813//create pole save
815let create_save = {814export let create_save = {
816 name: '',815 name: '',
817 description: '',816 description: '',
818 creator_notes: '',817 creator_notes: '',
@@ -864,7 +863,7 @@ export let amount_gen = 80; //default max length of AI generated responses
864export let max_context = 2048;863export let max_context = 2048;
865864
866var swipes = true;865var swipes = true;
867let extension_prompts = {};866export let extension_prompts = {};
868867
869export let main_api;// = "kobold";868export let main_api;// = "kobold";
870//novel settings869//novel settings
@@ -1175,7 +1174,7 @@ async function getStatusTextgen() {
1175 return resultCheckStatus();1174 return resultCheckStatus();
1176 }1175 }
11771176
1178 if (textgen_settings.type == OOBA && textgen_settings.bypass_status_check) {1177 if (textgen_settings.type == textgen_types.OOBA && textgen_settings.bypass_status_check) {
1179 setOnlineStatus('Status check bypassed');1178 setOnlineStatus('Status check bypassed');
1180 return resultCheckStatus();1179 return resultCheckStatus();
1181 }1180 }
@@ -1193,34 +1192,34 @@ async function getStatusTextgen() {
11931192
1194 const data = await response.json();1193 const data = await response.json();
11951194
1196 if (textgen_settings.type === MANCER) {1195 if (textgen_settings.type === textgen_types.MANCER) {
1197 loadMancerModels(data?.data);1196 loadMancerModels(data?.data);
1198 setOnlineStatus(textgen_settings.mancer_model);1197 setOnlineStatus(textgen_settings.mancer_model);
1199 } else if (textgen_settings.type === TOGETHERAI) {1198 } else if (textgen_settings.type === textgen_types.TOGETHERAI) {
1200 loadTogetherAIModels(data?.data);1199 loadTogetherAIModels(data?.data);
1201 setOnlineStatus(textgen_settings.togetherai_model);1200 setOnlineStatus(textgen_settings.togetherai_model);
1202 } else if (textgen_settings.type === OLLAMA) {1201 } else if (textgen_settings.type === textgen_types.OLLAMA) {
1203 loadOllamaModels(data?.data);1202 loadOllamaModels(data?.data);
1204 setOnlineStatus(textgen_settings.ollama_model || 'Connected');1203 setOnlineStatus(textgen_settings.ollama_model || 'Connected');
1205 } else if (textgen_settings.type === INFERMATICAI) {1204 } else if (textgen_settings.type === textgen_types.INFERMATICAI) {
1206 loadInfermaticAIModels(data?.data);1205 loadInfermaticAIModels(data?.data);
1207 setOnlineStatus(textgen_settings.infermaticai_model);1206 setOnlineStatus(textgen_settings.infermaticai_model);
1208 } else if (textgen_settings.type === DREAMGEN) {1207 } else if (textgen_settings.type === textgen_types.DREAMGEN) {
1209 loadDreamGenModels(data?.data);1208 loadDreamGenModels(data?.data);
1210 setOnlineStatus(textgen_settings.dreamgen_model);1209 setOnlineStatus(textgen_settings.dreamgen_model);
1211 } else if (textgen_settings.type === OPENROUTER) {1210 } else if (textgen_settings.type === textgen_types.OPENROUTER) {
1212 loadOpenRouterModels(data?.data);1211 loadOpenRouterModels(data?.data);
1213 setOnlineStatus(textgen_settings.openrouter_model);1212 setOnlineStatus(textgen_settings.openrouter_model);
1214 } else if (textgen_settings.type === VLLM) {1213 } else if (textgen_settings.type === textgen_types.VLLM) {
1215 loadVllmModels(data?.data);1214 loadVllmModels(data?.data);
1216 setOnlineStatus(textgen_settings.vllm_model);1215 setOnlineStatus(textgen_settings.vllm_model);
1217 } else if (textgen_settings.type === APHRODITE) {1216 } else if (textgen_settings.type === textgen_types.APHRODITE) {
1218 loadAphroditeModels(data?.data);1217 loadAphroditeModels(data?.data);
1219 setOnlineStatus(textgen_settings.aphrodite_model);1218 setOnlineStatus(textgen_settings.aphrodite_model);
1220 } else if (textgen_settings.type === FEATHERLESS) {1219 } else if (textgen_settings.type === textgen_types.FEATHERLESS) {
1221 loadFeatherlessModels(data?.data);1220 loadFeatherlessModels(data?.data);
1222 setOnlineStatus(textgen_settings.featherless_model);1221 setOnlineStatus(textgen_settings.featherless_model);
1223 } else if (textgen_settings.type === TABBY) {1222 } else if (textgen_settings.type === textgen_types.TABBY) {
1224 loadTabbyModels(data?.data);1223 loadTabbyModels(data?.data);
1225 setOnlineStatus(textgen_settings.tabby_model || data?.result);1224 setOnlineStatus(textgen_settings.tabby_model || data?.result);
1226 } else {1225 } else {
@@ -5542,7 +5541,7 @@ function extractMultiSwipes(data, type) {
5542 return swipes;5541 return swipes;
5543 }5542 }
55445543
5545 if (main_api === 'openai' || (main_api === 'textgenerationwebui' && [MANCER, VLLM, APHRODITE, TABBY, INFERMATICAI].includes(textgen_settings.type))) {5544 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))) {
5546 if (!Array.isArray(data.choices)) {5545 if (!Array.isArray(data.choices)) {
5547 return swipes;5546 return swipes;
5548 }5547 }
@@ -5705,7 +5704,7 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc
5705 return getMessage;5704 return getMessage;
5706}5705}
57075706
5708async function saveReply(type, getMessage, fromStreaming, title, swipes) {5707export async function saveReply(type, getMessage, fromStreaming, title, swipes) {
5709 if (type != 'append' && type != 'continue' && type != 'appendFinal' && chat.length && (chat[chat.length - 1]['swipe_id'] === undefined ||5708 if (type != 'append' && type != 'continue' && type != 'appendFinal' && chat.length && (chat[chat.length - 1]['swipe_id'] === undefined ||
5710 chat[chat.length - 1]['is_user'])) {5709 chat[chat.length - 1]['is_user'])) {
5711 type = 'normal';5710 type = 'normal';
@@ -8237,102 +8236,6 @@ async function createOrEditCharacter(e) {
8237 }8236 }
8238}8237}
82398238
8240window['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
8336/**8239/**
8337 * Formats a counter for a swipe view.8240 * Formats a counter for a swipe view.
8338 * @param {number} current The current number of items.8241 * @param {number} current The current number of items.
public/scripts/extensions.js+1 -1
@@ -5,6 +5,7 @@ import { showLoader } from './loader.js';
5import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';5import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
6import { renderTemplate, renderTemplateAsync } from './templates.js';6import { renderTemplate, renderTemplateAsync } from './templates.js';
7import { isSubsetOf, setValueByPath } from './utils.js';7import { isSubsetOf, setValueByPath } from './utils.js';
8import { getContext } from './st-context.js';
8export {9export {
9 getContext,10 getContext,
10 getApiUrl,11 getApiUrl,
@@ -174,7 +175,6 @@ const extension_settings = {
174let modules = [];175let modules = [];
175let activeExtensions = new Set();176let activeExtensions = new Set();
176177
177const getContext = () => window['SillyTavern'].getContext();
178const getApiUrl = () => extension_settings.apiUrl;178const getApiUrl = () => extension_settings.apiUrl;
179let connectedToApi = false;179let connectedToApi = false;
180180
public/scripts/st-context.js+170 -0
@@ -0,0 +1,170 @@
1import {
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';
44import {
45 extension_settings,
46 ModuleWorkerWrapper,
47 renderExtensionTemplate,
48 renderExtensionTemplateAsync,
49 writeExtensionField,
50} from './extensions.js';
51import { groups, openGroupChat, selected_group } from './group-chats.js';
52import { t, translate } from './i18n.js';
53import { hideLoader, showLoader } from './loader.js';
54import { MacrosParser } from './macros.js';
55import { oai_settings } from './openai.js';
56import { callGenericPopup, Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
57import { registerDebugFunction } from './power-user.js';
58import { isMobile, shouldSendOnEnter } from './RossAscends-mods.js';
59import { ScraperManager } from './scrapers.js';
60import { executeSlashCommands, executeSlashCommandsWithOptions, registerSlashCommand } from './slash-commands.js';
61import { SlashCommand } from './slash-commands/SlashCommand.js';
62import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js';
63import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
64import { tag_map, tags } from './tags.js';
65import { textgenerationwebui_settings } from './textgen-settings.js';
66import { getTokenCount, getTokenCountAsync, getTokenizerModel } from './tokenizers.js';
67import { ToolManager } from './tool-calling.js';
68import { timestampToMoment } from './utils.js';
69
70export 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
170export default getContext;
public/scripts/textgen-settings.js+7 -10
@@ -18,13 +18,6 @@ import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer }
18import { ENCODE_TOKENIZERS, TEXTGEN_TOKENIZERS, getTextTokens, tokenizers } from './tokenizers.js';18import { ENCODE_TOKENIZERS, TEXTGEN_TOKENIZERS, getTextTokens, tokenizers } from './tokenizers.js';
19import { getSortableDelay, onlyUnique } from './utils.js';19import { getSortableDelay, onlyUnique } from './utils.js';
2020
21export {
22 settings as textgenerationwebui_settings,
23 loadTextGenSettings,
24 generateTextGenWithStreaming,
25 formatTextGenURL,
26};
27
28export const textgen_types = {21export const textgen_types = {
29 OOBA: 'ooba',22 OOBA: 'ooba',
30 MANCER: 'mancer',23 MANCER: 'mancer',
@@ -197,6 +190,10 @@ const settings = {
197 featherless_model: '',190 featherless_model: '',
198};191};
199192
193export {
194 settings as textgenerationwebui_settings,
195};
196
200export let textgenerationwebui_banned_in_macros = [];197export let textgenerationwebui_banned_in_macros = [];
201198
202export let textgenerationwebui_presets = [];199export let textgenerationwebui_presets = [];
@@ -327,7 +324,7 @@ async function selectPreset(name) {
327 saveSettingsDebounced();324 saveSettingsDebounced();
328}325}
329326
330function formatTextGenURL(value) {327export function formatTextGenURL(value) {
331 try {328 try {
332 const noFormatTypes = [MANCER, TOGETHERAI, INFERMATICAI, DREAMGEN, OPENROUTER];329 const noFormatTypes = [MANCER, TOGETHERAI, INFERMATICAI, DREAMGEN, OPENROUTER];
333 if (noFormatTypes.includes(settings.type)) {330 if (noFormatTypes.includes(settings.type)) {
@@ -465,7 +462,7 @@ function calculateLogitBias() {
465 return result;462 return result;
466}463}
467464
468function loadTextGenSettings(data, loadedSettings) {465export function loadTextGenSettings(data, loadedSettings) {
469 textgenerationwebui_presets = convertPresets(data.textgenerationwebui_presets);466 textgenerationwebui_presets = convertPresets(data.textgenerationwebui_presets);
470 textgenerationwebui_preset_names = data.textgenerationwebui_preset_names ?? [];467 textgenerationwebui_preset_names = data.textgenerationwebui_preset_names ?? [];
471 Object.assign(settings, loadedSettings.textgenerationwebui_settings ?? {});468 Object.assign(settings, loadedSettings.textgenerationwebui_settings ?? {});
@@ -889,7 +886,7 @@ function setSettingByName(setting, value, trigger) {
889 * @returns {Promise<(function(): AsyncGenerator<{swipes: [], text: string, toolCalls: [], logprobs: {token: string, topLogprobs: Candidate[]}|null}, void, *>)|*>}886 * @returns {Promise<(function(): AsyncGenerator<{swipes: [], text: string, toolCalls: [], logprobs: {token: string, topLogprobs: Candidate[]}|null}, void, *>)|*>}
890 * @throws {Error} - If the response status is not OK, or from within the generator887 * @throws {Error} - If the response status is not OK, or from within the generator
891 */888 */
892async function generateTextGenWithStreaming(generate_data, signal) {889export async function generateTextGenWithStreaming(generate_data, signal) {
893 generate_data.stream = true;890 generate_data.stream = true;
894891
895 const response = await fetch('/api/backends/text-completions/generate', {892 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';
8import { textgen_types, textgenerationwebui_settings as textgen_settings, getTextGenServer, getTextGenModel } from './textgen-settings.js';8import { textgen_types, textgenerationwebui_settings as textgen_settings, getTextGenServer, getTextGenModel } from './textgen-settings.js';
9import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer, openRouterModels } from './textgen-models.js';9import { getCurrentDreamGenModelTokenizer, getCurrentOpenRouterModelTokenizer, openRouterModels } from './textgen-models.js';
1010
11const { OOBA, TABBY, KOBOLDCPP, VLLM, APHRODITE, LLAMACPP, OPENROUTER, DREAMGEN } = textgen_types;
12
13export const CHARACTERS_PER_TOKEN_RATIO = 3.35;11export const CHARACTERS_PER_TOKEN_RATIO = 3.35;
14export const TOKENIZER_WARNING_KEY = 'tokenizationWarningShown';12export const TOKENIZER_WARNING_KEY = 'tokenizationWarningShown';
15export const TOKENIZER_SUPPORTED_KEY = 'tokenizationSupported';13export const TOKENIZER_SUPPORTED_KEY = 'tokenizationSupported';
@@ -52,8 +50,12 @@ export const ENCODE_TOKENIZERS = [
52 //tokenizers.NERD2,50 //tokenizers.NERD2,
53];51];
5452
55// A list of Text Completion sources that support remote tokenization.53/**
56export 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 */
58export const TEXTGEN_TOKENIZERS = [];
5759
58const TOKENIZER_URLS = {60const TOKENIZER_URLS = {
59 [tokenizers.GPT2]: {61 [tokenizers.GPT2]: {
@@ -287,7 +289,7 @@ export function getTokenizerBestMatch(forApi) {
287 const hasTokenizerError = sessionStorage.getItem(TOKENIZER_WARNING_KEY);289 const hasTokenizerError = sessionStorage.getItem(TOKENIZER_WARNING_KEY);
288 const hasValidEndpoint = sessionStorage.getItem(TOKENIZER_SUPPORTED_KEY);290 const hasValidEndpoint = sessionStorage.getItem(TOKENIZER_SUPPORTED_KEY);
289 const isConnected = online_status !== 'no_connection';291 const isConnected = online_status !== 'no_connection';
290 const isTokenizerSupported = TEXTGEN_TOKENIZERS.includes(textgen_settings.type) && (textgen_settings.type !== OOBA || hasValidEndpoint);292 const isTokenizerSupported = TEXTGEN_TOKENIZERS.includes(textgen_settings.type) && (textgen_settings.type !== textgen_types.OOBA || hasValidEndpoint);
291293
292 if (!hasTokenizerError && isConnected) {294 if (!hasTokenizerError && isConnected) {
293 if (forApi === 'kobold' && kai_flags.can_use_tokenization) {295 if (forApi === 'kobold' && kai_flags.can_use_tokenization) {
@@ -297,10 +299,10 @@ export function getTokenizerBestMatch(forApi) {
297 if (forApi === 'textgenerationwebui' && isTokenizerSupported) {299 if (forApi === 'textgenerationwebui' && isTokenizerSupported) {
298 return tokenizers.API_TEXTGENERATIONWEBUI;300 return tokenizers.API_TEXTGENERATIONWEBUI;
299 }301 }
300 if (forApi === 'textgenerationwebui' && textgen_settings.type === OPENROUTER) {302 if (forApi === 'textgenerationwebui' && textgen_settings.type === textgen_types.OPENROUTER) {
301 return getCurrentOpenRouterModelTokenizer();303 return getCurrentOpenRouterModelTokenizer();
302 }304 }
303 if (forApi === 'textgenerationwebui' && textgen_settings.type === DREAMGEN) {305 if (forApi === 'textgenerationwebui' && textgen_settings.type === textgen_types.DREAMGEN) {
304 return getCurrentDreamGenModelTokenizer();306 return getCurrentDreamGenModelTokenizer();
305 }307 }
306 }308 }
@@ -576,7 +578,7 @@ export function getTokenizerModel() {
576578
577 // And for OpenRouter (if not a site model, then it's impossible to determine the tokenizer)579 // And for OpenRouter (if not a site model, then it's impossible to determine the tokenizer)
578 if (main_api == 'openai' && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER && oai_settings.openrouter_model ||580 if (main_api == 'openai' && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER && oai_settings.openrouter_model ||
579 main_api == 'textgenerationwebui' && textgen_settings.type === OPENROUTER && textgen_settings.openrouter_model) {581 main_api == 'textgenerationwebui' && textgen_settings.type === textgen_types.OPENROUTER && textgen_settings.openrouter_model) {
580 const model = main_api == 'openai'582 const model = main_api == 'openai'
581 ? model_list.find(x => x.id === oai_settings.openrouter_model)583 ? model_list.find(x => x.id === oai_settings.openrouter_model)
582 : openRouterModels.find(x => x.id === textgen_settings.openrouter_model);584 : openRouterModels.find(x => x.id === textgen_settings.openrouter_model);
@@ -652,7 +654,7 @@ export function getTokenizerModel() {
652 return oai_settings.custom_model;654 return oai_settings.custom_model;
653 }655 }
654656
655 if (oai_settings.chat_completion_source === chat_completion_sources.PERPLEXITY) {657 if (oai_settings.chat_completion_source === chat_completion_sources.PERPLEXITY) {
656 if (oai_settings.perplexity_model.includes('llama-3') || oai_settings.perplexity_model.includes('llama3')) {658 if (oai_settings.perplexity_model.includes('llama-3') || oai_settings.perplexity_model.includes('llama3')) {
657 return llama3Tokenizer;659 return llama3Tokenizer;
658 }660 }
@@ -680,7 +682,7 @@ export function getTokenizerModel() {
680 return yiTokenizer;682 return yiTokenizer;
681 }683 }
682684
683 if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) {685 if (oai_settings.chat_completion_source === chat_completion_sources.BLOCKENTROPY) {
684 if (oai_settings.blockentropy_model.includes('llama3')) {686 if (oai_settings.blockentropy_model.includes('llama3')) {
685 return llama3Tokenizer;687 return llama3Tokenizer;
686 }688 }
@@ -1121,6 +1123,14 @@ export function decodeTextTokens(tokenizerType, ids) {
1121}1123}
11221124
1123export async function initTokenizers() {1125export 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 );
1124 await loadTokenCache();1134 await loadTokenCache();
1125 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);1135 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);
1126}1136}