Add slash command to set tokenizer
| @@ -212,7 +212,7 @@ import { | ||
| 212 | 212 | selectContextPreset, |
| 213 | 213 | } from './scripts/instruct-mode.js'; |
| 214 | 214 | import { initLocales, t, translate } from './scripts/i18n.js'; |
| 215 | 215 | import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, getTokenizerModel, initTokenizers, saveTokenCache, selectTokenizer, TOKENIZER_NAME_MAP, tokenizers } from './scripts/tokenizers.js'; |
| 216 | 216 | import { |
| 217 | 217 | user_avatar, |
| 218 | 218 | getUserAvatars, |
| @@ -8451,6 +8451,25 @@ async function selectInstructCallback(_, name) { | ||
| 8451 | 8451 | return foundName; |
| 8452 | 8452 | } |
| 8453 | 8453 | |
| 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 | + | |
| 8454 | 8473 | async function enableInstructCallback() { |
| 8455 | 8474 | $('#instruct_enabled').prop('checked', true).trigger('change'); |
| 8456 | 8475 | return ''; |
| @@ -9096,6 +9115,28 @@ jQuery(async function () { | ||
| 9096 | 9115 | `, |
| 9097 | 9116 | })); |
| 9098 | 9117 | 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({ | |
| 9099 | 9140 | name: 'instruct-on', |
| 9100 | 9141 | callback: enableInstructCallback, |
| 9101 | 9142 | helpString: 'Enables instruct mode.', |
| @@ -148,6 +148,24 @@ async function resetTokenCache() { | ||
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | /** |
| 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 | +/** | |
| 151 | 169 | * Gets the friendly name of the current tokenizer. |
| 152 | 170 | * @param {string} forApi API to get the tokenizer for. Defaults to the main API. |
| 153 | 171 | * @returns { { tokenizerName: string, tokenizerId: number } } Tokenizer info |