Add slash command to set tokenizer

5f92b8a09e3638475756b575e4859f7f4e9f907a

Eugén Cowie <eugencowie@users.noreply.github.com>

2 files changed, +60 -1Ignore whitespace
public/script.js+42 -1
@@ -212,7 +212,7 @@ import {
212212 selectContextPreset,
213213} from './scripts/instruct-mode.js';
214214import { initLocales, t, translate } from './scripts/i18n.js';
215215import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, getTokenizerModel, initTokenizers, saveTokenCache, selectTokenizer, TOKENIZER_NAME_MAP, tokenizers } from './scripts/tokenizers.js';
216216import {
217217 user_avatar,
218218 getUserAvatars,
@@ -8451,6 +8451,25 @@ async function selectInstructCallback(_, name) {
84518451 return foundName;
84528452}
84538453
8454+async function selectTokenizerCallback(_, name) {
8455+ if (!name) {
8456+ return TOKENIZER_NAME_MAP[power_user.tokenizer];
8457+ }
8458+
8459+ const tokenizerNames = Object.values(TOKENIZER_NAME_MAP);
8460+ const fuse = new Fuse(tokenizerNames);
8461+ const result = fuse.search(name);
8462+
8463+ if (result.length === 0) {
8464+ toastr.warning(`Tokenizer "${name}" not found`);
8465+ return '';
8466+ }
8467+
8468+ const foundName = result[0].item;
8469+ selectTokenizer(tokenizers[foundName.toUpperCase()]);
8470+ return foundName;
8471+}
8472+
84548473async function enableInstructCallback() {
84558474 $('#instruct_enabled').prop('checked', true).trigger('change');
84568475 return '';
@@ -9096,6 +9115,28 @@ jQuery(async function () {
90969115 `,
90979116 }));
90989117 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
9118+ name: 'tokenizer',
9119+ callback: selectTokenizerCallback,
9120+ returns: 'current tokenizer',
9121+ unnamedArgumentList: [
9122+ SlashCommandArgument.fromProps({
9123+ description: 'tokenizer name',
9124+ typeList: [ARGUMENT_TYPE.STRING],
9125+ enumList: Object.values(TOKENIZER_NAME_MAP).map(tokenizer =>
9126+ new SlashCommandEnumValue(tokenizer, null, enumTypes.enum, enumIcons.default)),
9127+ }),
9128+ ],
9129+ helpString: `
9130+ <div>
9131+ Selects tokenizer by name. Gets the current tokenizer if no name is provided.
9132+ </div>
9133+ <div>
9134+ <strong>Available tokenizers:</strong>
9135+ <pre><code>${Object.values(TOKENIZER_NAME_MAP).join(', ')}</code></pre>
9136+ </div>
9137+ `
9138+ }));
9139+ SlashCommandParser.addCommandObject(SlashCommand.fromProps({
90999140 name: 'instruct-on',
91009141 callback: enableInstructCallback,
91019142 helpString: 'Enables instruct mode.',
public/scripts/tokenizers.js+18 -0
@@ -148,6 +148,24 @@ async function resetTokenCache() {
148148}
149149
150150/**
151+ * Maps tokenizer IDs to their names.
152+ * @example { 0: 'none', 1: 'gpt2', ... }
153+ */
154+export const TOKENIZER_NAME_MAP = Object.fromEntries(
155+ Object.entries(tokenizers).map(([name, id]) => [id, name.toLowerCase()]));
156+
157+/**
158+ * Selects tokenizer if not already selected.
159+ * @param {number} tokenizerId Tokenizer ID.
160+ */
161+export function selectTokenizer(tokenizerId) {
162+ if (tokenizerId !== power_user.tokenizer) {
163+ $('#tokenizer').val(tokenizerId).trigger('change');
164+ toastr.info(`Tokenizer: "${TOKENIZER_NAME_MAP[tokenizerId]}" selected`);
165+ }
166+}
167+
168+/**
151169 * Gets the friendly name of the current tokenizer.
152170 * @param {string} forApi API to get the tokenizer for. Defaults to the main API.
153171 * @returns { { tokenizerName: string, tokenizerId: number } } Tokenizer info