Merge pull request #2712 from SillyTavern/ai21-jamba New AI21 Jamba + tokenizer
Signed| @@ -8,7 +8,7 @@ | ||
| 8 | 8 | "openrouter_force_instruct": false, |
| 9 | 9 | "openrouter_group_models": false, |
| 10 | 10 | "openrouter_sort_models": "alphabetically", |
| 11 | 11 | "ai21_model": "j2jamba-ultra1.5-large", |
| 12 | 12 | "mistralai_model": "mistral-large-latest", |
| 13 | 13 | "custom_model": "", |
| 14 | 14 | "custom_url": "", |
| @@ -19,7 +19,6 @@ | ||
| 19 | 19 | "temperature": 1, |
| 20 | 20 | "frequency_penalty": 0, |
| 21 | 21 | "presence_penalty": 0, |
| 22 | - "count_penalty": 0, | |
| 23 | 22 | "top_p": 1, |
| 24 | 23 | "top_k": 0, |
| 25 | 24 | "top_a": 0, |
| @@ -233,8 +232,6 @@ | ||
| 233 | 232 | "assistant_prefill": "", |
| 234 | 233 | "assistant_impersonation": "", |
| 235 | 234 | "human_sysprompt_message": "Let's get started. Please generate your response based on the information and instructions provided above.", |
| 236 | - "use_ai21_tokenizer": false, | |
| 237 | - "use_google_tokenizer": false, | |
| 238 | 235 | "claude_use_sysprompt": false, |
| 239 | 236 | "use_alt_scale": false, |
| 240 | 237 | "squash_system_messages": false, |
| @@ -452,7 +452,6 @@ | ||
| 452 | 452 | "temp_openai": 1.0, |
| 453 | 453 | "freq_pen_openai": 0, |
| 454 | 454 | "pres_pen_openai": 0, |
| 455 | - "count_pen": 0, | |
| 456 | 455 | "top_p_openai": 1, |
| 457 | 456 | "top_k_openai": 0, |
| 458 | 457 | "stream_openai": true, |
| @@ -614,7 +613,7 @@ | ||
| 614 | 613 | "wi_format": "{0}", |
| 615 | 614 | "openai_model": "gpt-4-turbo", |
| 616 | 615 | "claude_model": "claude-3-5-sonnet-20240620", |
| 617 | 616 | "ai21_model": "j2jamba-ultra1.5-large", |
| 618 | 617 | "windowai_model": "", |
| 619 | 618 | "openrouter_model": "OR_Website", |
| 620 | 619 | "jailbreak_system": true, |
| @@ -625,7 +624,6 @@ | ||
| 625 | 624 | "show_external_models": false, |
| 626 | 625 | "proxy_password": "", |
| 627 | 626 | "assistant_prefill": "", |
| 628 | 627 | "assistant_impersonation": "", |
| 629 | - "use_ai21_tokenizer": false | |
| 630 | 628 | } |
| 631 | 629 | } |
| @@ -436,7 +436,7 @@ | ||
| 436 | 436 | </div> |
| 437 | 437 | </div> |
| 438 | 438 | </div> |
| 439 | 439 | <div data-newbie-hidden class="range-block" data-source="openai,openrouter,ai21,custom,cohere,perplexity,groq"> |
| 440 | 440 | <div class="range-block-title" data-i18n="Frequency Penalty"> |
| 441 | 441 | Frequency Penalty |
| 442 | 442 | </div> |
| @@ -449,7 +449,7 @@ | ||
| 449 | 449 | </div> |
| 450 | 450 | </div> |
| 451 | 451 | </div> |
| 452 | 452 | <div data-newbie-hidden class="range-block" data-source="openai,openrouter,ai21,custom,cohere,perplexity,groq"> |
| 453 | 453 | <div class="range-block-title" data-i18n="Presence Penalty"> |
| 454 | 454 | Presence Penalty |
| 455 | 455 | </div> |
| @@ -462,20 +462,7 @@ | ||
| 462 | 462 | </div> |
| 463 | 463 | </div> |
| 464 | 464 | </div> |
| 465 | 465 | <div data-newbie-hidden class="range-block" data-source="ai21claude,openrouter,makersuite,cohere,perplexity"> |
| 466 | - <div class="range-block-title" data-i18n="Count Penalty"> | |
| 467 | - Count Penalty | |
| 468 | - </div> | |
| 469 | - <div class="range-block-range-and-counter"> | |
| 470 | - <div class="range-block-range"> | |
| 471 | - <input type="range" id="count_pen" name="volume" min="0" max="1" step="0.01"> | |
| 472 | - </div> | |
| 473 | - <div class="range-block-counter"> | |
| 474 | - <input type="number" min="0" max="1" step="0.01" data-for="count_pen" id="count_pen_counter"> | |
| 475 | - </div> | |
| 476 | - </div> | |
| 477 | - </div> | |
| 478 | - <div data-newbie-hidden class="range-block" data-source="claude,openrouter,ai21,makersuite,cohere,perplexity"> | |
| 479 | 466 | <div class="range-block-title" data-i18n="Top K"> |
| 480 | 467 | Top K |
| 481 | 468 | </div> |
| @@ -1791,22 +1778,6 @@ | ||
| 1791 | 1778 | </select> |
| 1792 | 1779 | </div> |
| 1793 | 1780 | </div> |
| 1794 | - <div class="range-block" data-source="ai21"> | |
| 1795 | - <label for="use_ai21_tokenizer" title="Use AI21 Tokenizer" data-i18n="[title]Use AI21 Tokenizer" class="checkbox_label widthFreeExpand"> | |
| 1796 | - <input id="use_ai21_tokenizer" type="checkbox" /><span data-i18n="Use AI21 Tokenizer">Use AI21 Tokenizer</span> | |
| 1797 | - </label> | |
| 1798 | - <div class="toggle-description justifyLeft"> | |
| 1799 | - <span data-i18n="Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.">Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.</span> | |
| 1800 | - </div> | |
| 1801 | - </div> | |
| 1802 | - <div class="range-block" data-source="makersuite"> | |
| 1803 | - <label for="use_google_tokenizer" title="Use Google Tokenizer" data-i18n="[title]Use Google Tokenizer" class="checkbox_label widthFreeExpand"> | |
| 1804 | - <input id="use_google_tokenizer" type="checkbox" /><span data-i18n="Use Google Tokenizer">Use Google Tokenizer</span> | |
| 1805 | - </label> | |
| 1806 | - <div class="toggle-description justifyLeft"> | |
| 1807 | - <span data-i18n="Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.">Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.</span> | |
| 1808 | - </div> | |
| 1809 | - </div> | |
| 1810 | 1781 | <div class="range-block" data-source="makersuite"> |
| 1811 | 1782 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> |
| 1812 | 1783 | <input id="use_makersuite_sysprompt" type="checkbox" /> |
| @@ -2791,10 +2762,12 @@ | ||
| 2791 | 2762 | <div> |
| 2792 | 2763 | <h4 data-i18n="AI21 Model">AI21 Model</h4> |
| 2793 | 2764 | <select id="model_ai21_select"> |
| 2794 | 2765 | <optgroup label="LatestJamba 1.5"> |
| 2795 | 2766 | <option value="j2jamba-ultra1.5-mini">j2jamba-ultra1.5-mini</option> |
| 2796 | 2767 | <option value="j2jamba-mid1.5-large">j2jamba-mid1.5-large</option> |
| 2797 | - <option value="j2-light">j2-light</option> | |
| 2768 | + </optgroup> | |
| 2769 | + <optgroup label="Jamba-Instruct (Deprecated)"> | |
| 2770 | + <option value="jamba-instruct-preview">jamba-instruct-preview</option> | |
| 2798 | 2771 | </optgroup> |
| 2799 | 2772 | </select> |
| 2800 | 2773 | </div> |
| @@ -3450,6 +3423,7 @@ | ||
| 3450 | 3423 | <option value="3">Llama 1/2</option> |
| 3451 | 3424 | <option value="12">Llama 3</option> |
| 3452 | 3425 | <option value="13">Gemma / Gemini</option> |
| 3426 | + <option value="14">Jamba</option> | |
| 3453 | 3427 | <option value="4">NerdStash (NovelAI Clio)</option> |
| 3454 | 3428 | <option value="5">NerdStash v2 (NovelAI Kayra)</option> |
| 3455 | 3429 | <option value="7">Mistral</option> |
| @@ -2826,7 +2826,7 @@ export function getCharacterCardFields() { | ||
| 2826 | 2826 | } |
| 2827 | 2827 | |
| 2828 | 2828 | export function isStreamingEnabled() { |
| 2829 | 2829 | const noStreamSources = [chat_completion_sources.SCALE, chat_completion_sources.AI21]; |
| 2830 | 2830 | return ((main_api == 'openai' && oai_settings.stream_openai && !noStreamSources.includes(oai_settings.chat_completion_source) && !(oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE && oai_settings.google_model.includes('bison'))) |
| 2831 | 2831 | || (main_api == 'kobold' && kai_settings.streaming_kobold && kai_flags.can_use_streaming) |
| 2832 | 2832 | || (main_api == 'novel' && nai_settings.streaming_novel) |
| @@ -132,13 +132,9 @@ const max_2mil = 2000 * 1000; | ||
| 132 | 132 | const scale_max = 8191; |
| 133 | 133 | const claude_max = 9000; // We have a proper tokenizer, so theoretically could be larger (up to 9k) |
| 134 | 134 | const claude_100k_max = 99000; |
| 135 | -let ai21_max = 9200; //can easily fit 9k gpt tokens because j2's tokenizer is efficient af | |
| 136 | 135 | const unlocked_max = max_200k; |
| 137 | 136 | const oai_max_temp = 2.0; |
| 138 | 137 | const claude_max_temp = 1.0; //same as j2 |
| 139 | -const j2_max_topk = 10.0; | |
| 140 | -const j2_max_freq = 5.0; | |
| 141 | -const j2_max_pres = 5.0; | |
| 142 | 138 | const openrouter_website_model = 'OR_Website'; |
| 143 | 139 | const openai_max_stop_strings = 4; |
| 144 | 140 | |
| @@ -218,25 +214,11 @@ const sensitiveFields = [ | ||
| 218 | 214 | 'custom_include_headers', |
| 219 | 215 | ]; |
| 220 | 216 | |
| 221 | -function getPrefixMap() { | |
| 222 | - return selected_group ? { | |
| 223 | - assistant: '', | |
| 224 | - user: '', | |
| 225 | - system: 'OOC: ', | |
| 226 | - } | |
| 227 | - : { | |
| 228 | - assistant: '{{char}}:', | |
| 229 | - user: '{{user}}:', | |
| 230 | - system: '', | |
| 231 | - }; | |
| 232 | -} | |
| 233 | - | |
| 234 | 217 | const default_settings = { |
| 235 | 218 | preset_settings_openai: 'Default', |
| 236 | 219 | temp_openai: 1.0, |
| 237 | 220 | freq_pen_openai: 0, |
| 238 | 221 | pres_pen_openai: 0, |
| 239 | - count_pen: 0.0, | |
| 240 | 222 | top_p_openai: 1.0, |
| 241 | 223 | top_k_openai: 0, |
| 242 | 224 | min_p_openai: 0, |
| @@ -264,7 +246,7 @@ const default_settings = { | ||
| 264 | 246 | openai_model: 'gpt-4-turbo', |
| 265 | 247 | claude_model: 'claude-3-5-sonnet-20240620', |
| 266 | 248 | google_model: 'gemini-1.5-pro', |
| 267 | 249 | ai21_model: 'j2jamba-ultra1.5-large', |
| 268 | 250 | mistralai_model: 'mistral-large-latest', |
| 269 | 251 | cohere_model: 'command-r-plus', |
| 270 | 252 | perplexity_model: 'llama-3.1-70b-instruct', |
| @@ -294,8 +276,6 @@ const default_settings = { | ||
| 294 | 276 | assistant_prefill: '', |
| 295 | 277 | assistant_impersonation: '', |
| 296 | 278 | human_sysprompt_message: default_claude_human_sysprompt_message, |
| 297 | - use_ai21_tokenizer: false, | |
| 298 | - use_google_tokenizer: false, | |
| 299 | 279 | claude_use_sysprompt: false, |
| 300 | 280 | use_makersuite_sysprompt: true, |
| 301 | 281 | use_alt_scale: false, |
| @@ -317,7 +297,6 @@ const oai_settings = { | ||
| 317 | 297 | temp_openai: 1.0, |
| 318 | 298 | freq_pen_openai: 0, |
| 319 | 299 | pres_pen_openai: 0, |
| 320 | - count_pen: 0.0, | |
| 321 | 300 | top_p_openai: 1.0, |
| 322 | 301 | top_k_openai: 0, |
| 323 | 302 | min_p_openai: 0, |
| @@ -345,7 +324,7 @@ const oai_settings = { | ||
| 345 | 324 | openai_model: 'gpt-4-turbo', |
| 346 | 325 | claude_model: 'claude-3-5-sonnet-20240620', |
| 347 | 326 | google_model: 'gemini-1.5-pro', |
| 348 | 327 | ai21_model: 'j2jamba-ultra1.5-large', |
| 349 | 328 | mistralai_model: 'mistral-large-latest', |
| 350 | 329 | cohere_model: 'command-r-plus', |
| 351 | 330 | perplexity_model: 'llama-3.1-70b-instruct', |
| @@ -375,8 +354,6 @@ const oai_settings = { | ||
| 375 | 354 | assistant_prefill: '', |
| 376 | 355 | assistant_impersonation: '', |
| 377 | 356 | human_sysprompt_message: default_claude_human_sysprompt_message, |
| 378 | - use_ai21_tokenizer: false, | |
| 379 | - use_google_tokenizer: false, | |
| 380 | 357 | claude_use_sysprompt: false, |
| 381 | 358 | use_makersuite_sysprompt: true, |
| 382 | 359 | use_alt_scale: false, |
| @@ -1802,7 +1779,6 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1802 | 1779 | const isClaude = oai_settings.chat_completion_source == chat_completion_sources.CLAUDE; |
| 1803 | 1780 | const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER; |
| 1804 | 1781 | const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE; |
| 1805 | - const isAI21 = oai_settings.chat_completion_source == chat_completion_sources.AI21; | |
| 1806 | 1782 | const isGoogle = oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE; |
| 1807 | 1783 | const isOAI = oai_settings.chat_completion_source == chat_completion_sources.OPENAI; |
| 1808 | 1784 | const isMistral = oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI; |
| @@ -1815,7 +1791,7 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1815 | 1791 | const isQuiet = type === 'quiet'; |
| 1816 | 1792 | const isImpersonate = type === 'impersonate'; |
| 1817 | 1793 | const isContinue = type === 'continue'; |
| 1818 | 1794 | const stream = oai_settings.stream_openai && !isQuiet && !isScale && !isAI21 && !(isGoogle && oai_settings.google_model.includes('bison')); |
| 1819 | 1795 | const useLogprobs = !!power_user.request_token_probabilities; |
| 1820 | 1796 | const canMultiSwipe = oai_settings.n > 1 && !isContinue && !isImpersonate && !isQuiet && (isOAI || isCustom); |
| 1821 | 1797 | |
| @@ -1824,15 +1800,6 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1824 | 1800 | replaceItemizedPromptText(messageId, messages); |
| 1825 | 1801 | } |
| 1826 | 1802 | |
| 1827 | - if (isAI21) { | |
| 1828 | - const joinedMsgs = messages.reduce((acc, obj) => { | |
| 1829 | - const prefix = getPrefixMap()[obj.role]; | |
| 1830 | - return acc + (prefix ? (selected_group ? '\n' : prefix + ' ') : '') + obj.content + '\n'; | |
| 1831 | - }, ''); | |
| 1832 | - messages = substituteParams(joinedMsgs) + (isImpersonate ? `${name1}:` : `${name2}:`); | |
| 1833 | - replaceItemizedPromptText(messageId, messages); | |
| 1834 | - } | |
| 1835 | - | |
| 1836 | 1803 | // If we're using the window.ai extension, use that instead |
| 1837 | 1804 | // Doesn't support logit bias yet |
| 1838 | 1805 | if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) { |
| @@ -1931,12 +1898,6 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1931 | 1898 | generate_data['use_makersuite_sysprompt'] = oai_settings.use_makersuite_sysprompt; |
| 1932 | 1899 | } |
| 1933 | 1900 | |
| 1934 | - if (isAI21) { | |
| 1935 | - generate_data['top_k'] = Number(oai_settings.top_k_openai); | |
| 1936 | - generate_data['count_pen'] = Number(oai_settings.count_pen); | |
| 1937 | - generate_data['stop_tokens'] = [name1 + ':', substituteParams(oai_settings.new_chat_prompt), substituteParams(oai_settings.new_group_chat_prompt)]; | |
| 1938 | - } | |
| 1939 | - | |
| 1940 | 1901 | if (isMistral) { |
| 1941 | 1902 | generate_data['safe_prompt'] = false; // already defaults to false, but just incase they change that in the future. |
| 1942 | 1903 | } |
| @@ -3008,7 +2969,6 @@ function loadOpenAISettings(data, settings) { | ||
| 3008 | 2969 | oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai; |
| 3009 | 2970 | oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai; |
| 3010 | 2971 | oai_settings.pres_pen_openai = settings.pres_pen_openai ?? default_settings.pres_pen_openai; |
| 3011 | - oai_settings.count_pen = settings.count_pen ?? default_settings.count_pen; | |
| 3012 | 2972 | oai_settings.top_p_openai = settings.top_p_openai ?? default_settings.top_p_openai; |
| 3013 | 2973 | oai_settings.top_k_openai = settings.top_k_openai ?? default_settings.top_k_openai; |
| 3014 | 2974 | oai_settings.top_a_openai = settings.top_a_openai ?? default_settings.top_a_openai; |
| @@ -3080,10 +3040,12 @@ function loadOpenAISettings(data, settings) { | ||
| 3080 | 3040 | oai_settings.names_behavior = character_names_behavior.COMPLETION; |
| 3081 | 3041 | } |
| 3082 | 3042 | |
| 3043 | + if (oai_settings.ai21_model.startsWith('j2-')) { | |
| 3044 | + oai_settings.ai21_model = 'jamba-1.5-large'; | |
| 3045 | + } | |
| 3046 | + | |
| 3083 | 3047 | if (settings.wrap_in_quotes !== undefined) oai_settings.wrap_in_quotes = !!settings.wrap_in_quotes; |
| 3084 | 3048 | if (settings.openai_model !== undefined) oai_settings.openai_model = settings.openai_model; |
| 3085 | - if (settings.use_ai21_tokenizer !== undefined) { oai_settings.use_ai21_tokenizer = !!settings.use_ai21_tokenizer; oai_settings.use_ai21_tokenizer ? ai21_max = 8191 : ai21_max = 9200; } | |
| 3086 | - if (settings.use_google_tokenizer !== undefined) oai_settings.use_google_tokenizer = !!settings.use_google_tokenizer; | |
| 3087 | 3049 | if (settings.claude_use_sysprompt !== undefined) oai_settings.claude_use_sysprompt = !!settings.claude_use_sysprompt; |
| 3088 | 3050 | if (settings.use_makersuite_sysprompt !== undefined) oai_settings.use_makersuite_sysprompt = !!settings.use_makersuite_sysprompt; |
| 3089 | 3051 | if (settings.use_alt_scale !== undefined) { oai_settings.use_alt_scale = !!settings.use_alt_scale; updateScaleForm(); } |
| @@ -3133,8 +3095,6 @@ function loadOpenAISettings(data, settings) { | ||
| 3133 | 3095 | $('#jailbreak_system').prop('checked', oai_settings.jailbreak_system); |
| 3134 | 3096 | $('#openai_show_external_models').prop('checked', oai_settings.show_external_models); |
| 3135 | 3097 | $('#openai_external_category').toggle(oai_settings.show_external_models); |
| 3136 | - $('#use_ai21_tokenizer').prop('checked', oai_settings.use_ai21_tokenizer); | |
| 3137 | - $('#use_google_tokenizer').prop('checked', oai_settings.use_google_tokenizer); | |
| 3138 | 3098 | $('#claude_use_sysprompt').prop('checked', oai_settings.claude_use_sysprompt); |
| 3139 | 3099 | $('#use_makersuite_sysprompt').prop('checked', oai_settings.use_makersuite_sysprompt); |
| 3140 | 3100 | $('#scale-alt').prop('checked', oai_settings.use_alt_scale); |
| @@ -3170,9 +3130,6 @@ function loadOpenAISettings(data, settings) { | ||
| 3170 | 3130 | $('#pres_pen_openai').val(oai_settings.pres_pen_openai); |
| 3171 | 3131 | $('#pres_pen_counter_openai').val(Number(oai_settings.pres_pen_openai).toFixed(2)); |
| 3172 | 3132 | |
| 3173 | - $('#count_pen').val(oai_settings.count_pen); | |
| 3174 | - $('#count_pen_counter').val(Number(oai_settings.count_pen).toFixed(2)); | |
| 3175 | - | |
| 3176 | 3133 | $('#top_p_openai').val(oai_settings.top_p_openai); |
| 3177 | 3134 | $('#top_p_counter_openai').val(Number(oai_settings.top_p_openai).toFixed(2)); |
| 3178 | 3135 | |
| @@ -3392,7 +3349,6 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | ||
| 3392 | 3349 | temperature: settings.temp_openai, |
| 3393 | 3350 | frequency_penalty: settings.freq_pen_openai, |
| 3394 | 3351 | presence_penalty: settings.pres_pen_openai, |
| 3395 | - count_penalty: settings.count_pen, | |
| 3396 | 3352 | top_p: settings.top_p_openai, |
| 3397 | 3353 | top_k: settings.top_k_openai, |
| 3398 | 3354 | top_a: settings.top_a_openai, |
| @@ -3427,8 +3383,6 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | ||
| 3427 | 3383 | assistant_prefill: settings.assistant_prefill, |
| 3428 | 3384 | assistant_impersonation: settings.assistant_impersonation, |
| 3429 | 3385 | human_sysprompt_message: settings.human_sysprompt_message, |
| 3430 | - use_ai21_tokenizer: settings.use_ai21_tokenizer, | |
| 3431 | - use_google_tokenizer: settings.use_google_tokenizer, | |
| 3432 | 3386 | claude_use_sysprompt: settings.claude_use_sysprompt, |
| 3433 | 3387 | use_makersuite_sysprompt: settings.use_makersuite_sysprompt, |
| 3434 | 3388 | use_alt_scale: settings.use_alt_scale, |
| @@ -3799,7 +3753,6 @@ function onSettingsPresetChange() { | ||
| 3799 | 3753 | temperature: ['#temp_openai', 'temp_openai', false], |
| 3800 | 3754 | frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false], |
| 3801 | 3755 | presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false], |
| 3802 | - count_penalty: ['#count_pen', 'count_pen', false], | |
| 3803 | 3756 | top_p: ['#top_p_openai', 'top_p_openai', false], |
| 3804 | 3757 | top_k: ['#top_k_openai', 'top_k_openai', false], |
| 3805 | 3758 | top_a: ['#top_a_openai', 'top_a_openai', false], |
| @@ -3856,8 +3809,6 @@ function onSettingsPresetChange() { | ||
| 3856 | 3809 | assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false], |
| 3857 | 3810 | assistant_impersonation: ['#claude_assistant_impersonation', 'assistant_impersonation', false], |
| 3858 | 3811 | human_sysprompt_message: ['#claude_human_sysprompt_textarea', 'human_sysprompt_message', false], |
| 3859 | - use_ai21_tokenizer: ['#use_ai21_tokenizer', 'use_ai21_tokenizer', true], | |
| 3860 | - use_google_tokenizer: ['#use_google_tokenizer', 'use_google_tokenizer', true], | |
| 3861 | 3812 | claude_use_sysprompt: ['#claude_use_sysprompt', 'claude_use_sysprompt', true], |
| 3862 | 3813 | use_makersuite_sysprompt: ['#use_makersuite_sysprompt', 'use_makersuite_sysprompt', true], |
| 3863 | 3814 | use_alt_scale: ['#use_alt_scale', 'use_alt_scale', true], |
| @@ -4028,6 +3979,11 @@ async function onModelChange() { | ||
| 4028 | 3979 | } |
| 4029 | 3980 | |
| 4030 | 3981 | if ($(this).is('#model_ai21_select')) { |
| 3982 | + if (value === '' || value.startsWith('j2-')) { | |
| 3983 | + value = 'jamba-1.5-large'; | |
| 3984 | + $('#model_ai21_select').val(value); | |
| 3985 | + } | |
| 3986 | + | |
| 4031 | 3987 | console.log('AI21 model changed to', value); |
| 4032 | 3988 | oai_settings.ai21_model = value; |
| 4033 | 3989 | } |
| @@ -4305,33 +4261,13 @@ async function onModelChange() { | ||
| 4305 | 4261 | if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { |
| 4306 | 4262 | if (oai_settings.max_context_unlocked) { |
| 4307 | 4263 | $('#openai_max_context').attr('max', unlocked_max); |
| 4308 | - } else { | |
| 4264 | + } else if (oai_settings.ai21_model.includes('jamba-1.5') || oai_settings.ai21_model.includes('jamba-instruct')) { | |
| 4309 | 4265 | $('#openai_max_context').attr('max', ai21_maxmax_256k); |
| 4310 | 4266 | } |
| 4311 | 4267 | |
| 4312 | 4268 | oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context); |
| 4313 | 4269 | $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); |
| 4314 | - | |
| 4270 | + $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | |
| 4315 | - oai_settings.temp_openai = Math.min(claude_max_temp, oai_settings.temp_openai); | |
| 4316 | - $('#temp_openai').attr('max', claude_max_temp).val(oai_settings.temp_openai).trigger('input'); | |
| 4317 | - | |
| 4318 | - oai_settings.freq_pen_openai = Math.min(j2_max_freq, oai_settings.freq_pen_openai < 0 ? 0 : oai_settings.freq_pen_openai); | |
| 4319 | - $('#freq_pen_openai').attr('min', 0).attr('max', j2_max_freq).val(oai_settings.freq_pen_openai).trigger('input'); | |
| 4320 | - | |
| 4321 | - oai_settings.pres_pen_openai = Math.min(j2_max_pres, oai_settings.pres_pen_openai < 0 ? 0 : oai_settings.pres_pen_openai); | |
| 4322 | - $('#pres_pen_openai').attr('min', 0).attr('max', j2_max_pres).val(oai_settings.pres_pen_openai).trigger('input'); | |
| 4323 | - | |
| 4324 | - oai_settings.top_k_openai = Math.min(j2_max_topk, oai_settings.top_k_openai); | |
| 4325 | - $('#top_k_openai').attr('max', j2_max_topk).val(oai_settings.top_k_openai).trigger('input'); | |
| 4326 | - } else if (oai_settings.chat_completion_source != chat_completion_sources.AI21) { | |
| 4327 | - oai_settings.freq_pen_openai = Math.min(2.0, oai_settings.freq_pen_openai); | |
| 4328 | - $('#freq_pen_openai').attr('min', -2.0).attr('max', 2.0).val(oai_settings.freq_pen_openai).trigger('input'); | |
| 4329 | - | |
| 4330 | - oai_settings.pres_pen_openai = Math.min(2.0, oai_settings.pres_pen_openai); | |
| 4331 | - $('#pres_pen_openai').attr('min', -2.0).attr('max', 2.0).val(oai_settings.pres_pen_openai).trigger('input'); | |
| 4332 | - | |
| 4333 | - oai_settings.top_k_openai = Math.min(200, oai_settings.top_k_openai); | |
| 4334 | - $('#top_k_openai').attr('max', 200).val(oai_settings.top_k_openai).trigger('input'); | |
| 4335 | 4271 | } |
| 4336 | 4272 | |
| 4337 | 4273 | if (oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) { |
| @@ -4953,12 +4889,6 @@ $(document).ready(async function () { | ||
| 4953 | 4889 | saveSettingsDebounced(); |
| 4954 | 4890 | }); |
| 4955 | 4891 | |
| 4956 | - $('#count_pen').on('input', function () { | |
| 4957 | - oai_settings.count_pen = Number($(this).val()); | |
| 4958 | - $('#count_pen_counter').val(Number($(this).val()).toFixed(2)); | |
| 4959 | - saveSettingsDebounced(); | |
| 4960 | - }); | |
| 4961 | - | |
| 4962 | 4892 | $('#top_p_openai').on('input', function () { |
| 4963 | 4893 | oai_settings.top_p_openai = Number($(this).val()); |
| 4964 | 4894 | $('#top_p_counter_openai').val(Number($(this).val()).toFixed(2)); |
| @@ -5017,20 +4947,6 @@ $(document).ready(async function () { | ||
| 5017 | 4947 | saveSettingsDebounced(); |
| 5018 | 4948 | }); |
| 5019 | 4949 | |
| 5020 | - $('#use_ai21_tokenizer').on('change', function () { | |
| 5021 | - oai_settings.use_ai21_tokenizer = !!$('#use_ai21_tokenizer').prop('checked'); | |
| 5022 | - oai_settings.use_ai21_tokenizer ? ai21_max = 8191 : ai21_max = 9200; | |
| 5023 | - oai_settings.openai_max_context = Math.min(ai21_max, oai_settings.openai_max_context); | |
| 5024 | - $('#openai_max_context').attr('max', ai21_max).val(oai_settings.openai_max_context).trigger('input'); | |
| 5025 | - $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); | |
| 5026 | - saveSettingsDebounced(); | |
| 5027 | - }); | |
| 5028 | - | |
| 5029 | - $('#use_google_tokenizer').on('change', function () { | |
| 5030 | - oai_settings.use_google_tokenizer = !!$('#use_google_tokenizer').prop('checked'); | |
| 5031 | - saveSettingsDebounced(); | |
| 5032 | - }); | |
| 5033 | - | |
| 5034 | 4950 | $('#claude_use_sysprompt').on('change', function () { |
| 5035 | 4951 | oai_settings.claude_use_sysprompt = !!$('#claude_use_sysprompt').prop('checked'); |
| 5036 | 4952 | $('#claude_human_sysprompt_message_block').toggle(oai_settings.claude_use_sysprompt); |
| @@ -27,6 +27,7 @@ export const tokenizers = { | ||
| 27 | 27 | CLAUDE: 11, |
| 28 | 28 | LLAMA3: 12, |
| 29 | 29 | GEMMA: 13, |
| 30 | + JAMBA: 14, | |
| 30 | 31 | BEST_MATCH: 99, |
| 31 | 32 | }; |
| 32 | 33 | |
| @@ -36,6 +37,7 @@ export const SENTENCEPIECE_TOKENIZERS = [ | ||
| 36 | 37 | tokenizers.YI, |
| 37 | 38 | tokenizers.LLAMA3, |
| 38 | 39 | tokenizers.GEMMA, |
| 40 | + tokenizers.JAMBA, | |
| 39 | 41 | // uncomment when NovelAI releases Kayra and Clio weights, lol |
| 40 | 42 | //tokenizers.NERD, |
| 41 | 43 | //tokenizers.NERD2, |
| @@ -98,6 +100,11 @@ const TOKENIZER_URLS = { | ||
| 98 | 100 | decode: '/api/tokenizers/gemma/decode', |
| 99 | 101 | count: '/api/tokenizers/gemma/encode', |
| 100 | 102 | }, |
| 103 | + [tokenizers.JAMBA]: { | |
| 104 | + encode: '/api/tokenizers/jamba/encode', | |
| 105 | + decode: '/api/tokenizers/jamba/decode', | |
| 106 | + count: '/api/tokenizers/jamba/encode', | |
| 107 | + }, | |
| 101 | 108 | [tokenizers.API_TEXTGENERATIONWEBUI]: { |
| 102 | 109 | encode: '/api/tokenizers/remote/textgenerationwebui/encode', |
| 103 | 110 | count: '/api/tokenizers/remote/textgenerationwebui/encode', |
| @@ -164,7 +171,7 @@ export function getAvailableTokenizers() { | ||
| 164 | 171 | tokenizerId: Number(tokenizerOption.value), |
| 165 | 172 | tokenizerKey: Object.entries(tokenizers).find(([_, value]) => value === Number(tokenizerOption.value))[0].toLocaleLowerCase(), |
| 166 | 173 | tokenizerName: tokenizerOption.text, |
| 167 | 174 | })); |
| 168 | 175 | } |
| 169 | 176 | |
| 170 | 177 | /** |
| @@ -280,6 +287,12 @@ export function getTokenizerBestMatch(forApi) { | ||
| 280 | 287 | if (model.includes('gemma')) { |
| 281 | 288 | return tokenizers.GEMMA; |
| 282 | 289 | } |
| 290 | + if (model.includes('yi')) { | |
| 291 | + return tokenizers.YI; | |
| 292 | + } | |
| 293 | + if (model.includes('jamba')) { | |
| 294 | + return tokenizers.JAMBA; | |
| 295 | + } | |
| 283 | 296 | } |
| 284 | 297 | |
| 285 | 298 | return tokenizers.LLAMA; |
| @@ -497,6 +510,7 @@ export function getTokenizerModel() { | ||
| 497 | 510 | const mistralTokenizer = 'mistral'; |
| 498 | 511 | const yiTokenizer = 'yi'; |
| 499 | 512 | const gemmaTokenizer = 'gemma'; |
| 513 | + const jambaTokenizer = 'jamba'; | |
| 500 | 514 | |
| 501 | 515 | // Assuming no one would use it for different models.. right? |
| 502 | 516 | if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) { |
| @@ -562,12 +576,19 @@ export function getTokenizerModel() { | ||
| 562 | 576 | else if (oai_settings.openrouter_model.includes('GPT-NeoXT')) { |
| 563 | 577 | return gpt2Tokenizer; |
| 564 | 578 | } |
| 579 | + else if (oai_settings.openrouter_model.includes('jamba')) { | |
| 580 | + return jambaTokenizer; | |
| 581 | + } | |
| 565 | 582 | } |
| 566 | 583 | |
| 567 | 584 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { |
| 568 | 585 | return gemmaTokenizer; |
| 569 | 586 | } |
| 570 | 587 | |
| 588 | + if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { | |
| 589 | + return jambaTokenizer; | |
| 590 | + } | |
| 591 | + | |
| 571 | 592 | if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { |
| 572 | 593 | return claudeTokenizer; |
| 573 | 594 | } |
| @@ -626,16 +647,7 @@ export function getTokenizerModel() { | ||
| 626 | 647 | * @deprecated Use countTokensOpenAIAsync instead. |
| 627 | 648 | */ |
| 628 | 649 | export function countTokensOpenAI(messages, full = false) { |
| 629 | - const shouldTokenizeAI21 = oai_settings.chat_completion_source === chat_completion_sources.AI21 && oai_settings.use_ai21_tokenizer; | |
| 650 | + const tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; | |
| 630 | - const shouldTokenizeGoogle = oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE && oai_settings.use_google_tokenizer; | |
| 631 | - let tokenizerEndpoint = ''; | |
| 632 | - if (shouldTokenizeAI21) { | |
| 633 | - tokenizerEndpoint = '/api/tokenizers/ai21/count'; | |
| 634 | - } else if (shouldTokenizeGoogle) { | |
| 635 | - tokenizerEndpoint = `/api/tokenizers/google/count?model=${getTokenizerModel()}&reverse_proxy=${oai_settings.reverse_proxy}&proxy_password=${oai_settings.proxy_password}`; | |
| 636 | - } else { | |
| 637 | - tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; | |
| 638 | - } | |
| 639 | 651 | const cacheObject = getTokenCacheObject(); |
| 640 | 652 | |
| 641 | 653 | if (!Array.isArray(messages)) { |
| @@ -647,7 +659,7 @@ export function countTokensOpenAI(messages, full = false) { | ||
| 647 | 659 | for (const message of messages) { |
| 648 | 660 | const model = getTokenizerModel(); |
| 649 | 661 | |
| 650 | 662 | if (model === 'claude' || shouldTokenizeAI21 || shouldTokenizeGoogle) { |
| 651 | 663 | full = true; |
| 652 | 664 | } |
| 653 | 665 | |
| @@ -687,16 +699,7 @@ export function countTokensOpenAI(messages, full = false) { | ||
| 687 | 699 | * @returns {Promise<number>} Token count. |
| 688 | 700 | */ |
| 689 | 701 | export async function countTokensOpenAIAsync(messages, full = false) { |
| 690 | - const shouldTokenizeAI21 = oai_settings.chat_completion_source === chat_completion_sources.AI21 && oai_settings.use_ai21_tokenizer; | |
| 702 | + const tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; | |
| 691 | - const shouldTokenizeGoogle = oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE && oai_settings.use_google_tokenizer; | |
| 692 | - let tokenizerEndpoint = ''; | |
| 693 | - if (shouldTokenizeAI21) { | |
| 694 | - tokenizerEndpoint = '/api/tokenizers/ai21/count'; | |
| 695 | - } else if (shouldTokenizeGoogle) { | |
| 696 | - tokenizerEndpoint = `/api/tokenizers/google/count?model=${getTokenizerModel()}`; | |
| 697 | - } else { | |
| 698 | - tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; | |
| 699 | - } | |
| 700 | 703 | const cacheObject = getTokenCacheObject(); |
| 701 | 704 | |
| 702 | 705 | if (!Array.isArray(messages)) { |
| @@ -708,7 +711,7 @@ export async function countTokensOpenAIAsync(messages, full = false) { | ||
| 708 | 711 | for (const message of messages) { |
| 709 | 712 | const model = getTokenizerModel(); |
| 710 | 713 | |
| 711 | 714 | if (model === 'claude' || shouldTokenizeAI21 || shouldTokenizeGoogle) { |
| 712 | 715 | full = true; |
| 713 | 716 | } |
| 714 | 717 | |
| @@ -5,7 +5,7 @@ const Readable = require('stream').Readable; | ||
| 5 | 5 | const { jsonParser } = require('../../express-common'); |
| 6 | 6 | const { CHAT_COMPLETION_SOURCES, GEMINI_SAFETY, BISON_SAFETY, OPENROUTER_HEADERS } = require('../../constants'); |
| 7 | 7 | const { forwardFetchResponse, getConfigValue, tryParse, uuidv4, mergeObjectWithYaml, excludeKeysByYaml, color } = require('../../util'); |
| 8 | 8 | const { convertClaudeMessages, convertGooglePrompt, convertTextCompletionPrompt, convertCohereMessages, convertMistralMessages, convertCohereTools, convertAI21Messages } = require('../../prompt-converters'); |
| 9 | 9 | |
| 10 | 10 | const { readSecret, SECRET_KEYS } = require('../secrets'); |
| 11 | 11 | const { getTokenizerModel, getSentencepiceTokenizer, getTiktokenTokenizer, sentencepieceTokenizers, TEXT_COMPLETION_MODELS } = require('../tokenizers'); |
| @@ -19,6 +19,7 @@ const API_GROQ = 'https://api.groq.com/openai/v1'; | ||
| 19 | 19 | const API_MAKERSUITE = 'https://generativelanguage.googleapis.com'; |
| 20 | 20 | const API_01AI = 'https://api.01.ai/v1'; |
| 21 | 21 | const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1'; |
| 22 | +const API_AI21 = 'https://api.ai21.com/studio/v1'; | |
| 22 | 23 | |
| 23 | 24 | /** |
| 24 | 25 | * Applies a post-processing step to the generated messages. |
| @@ -413,6 +414,16 @@ async function sendAI21Request(request, response) { | ||
| 413 | 414 | request.socket.on('close', function () { |
| 414 | 415 | controller.abort(); |
| 415 | 416 | }); |
| 417 | + const convertedPrompt = convertAI21Messages(request.body.messages, request.body.char_name, request.body.user_name); | |
| 418 | + const body = { | |
| 419 | + messages: convertedPrompt, | |
| 420 | + model: request.body.model, | |
| 421 | + max_tokens: request.body.max_tokens, | |
| 422 | + temperature: request.body.temperature, | |
| 423 | + top_p: request.body.top_p, | |
| 424 | + stop: request.body.stop, | |
| 425 | + stream: request.body.stream, | |
| 426 | + }; | |
| 416 | 427 | const options = { |
| 417 | 428 | method: 'POST', |
| 418 | 429 | headers: { |
| @@ -420,59 +431,33 @@ async function sendAI21Request(request, response) { | ||
| 420 | 431 | 'content-type': 'application/json', |
| 421 | 432 | Authorization: `Bearer ${readSecret(request.user.directories, SECRET_KEYS.AI21)}`, |
| 422 | 433 | }, |
| 423 | 434 | body: JSON.stringify({body), |
| 424 | - numResults: 1, | |
| 425 | - maxTokens: request.body.max_tokens, | |
| 426 | - minTokens: 0, | |
| 427 | - temperature: request.body.temperature, | |
| 428 | - topP: request.body.top_p, | |
| 429 | - stopSequences: request.body.stop_tokens, | |
| 430 | - topKReturn: request.body.top_k, | |
| 431 | - frequencyPenalty: { | |
| 432 | - scale: request.body.frequency_penalty * 100, | |
| 433 | - applyToWhitespaces: false, | |
| 434 | - applyToPunctuations: false, | |
| 435 | - applyToNumbers: false, | |
| 436 | - applyToStopwords: false, | |
| 437 | - applyToEmojis: false, | |
| 438 | - }, | |
| 439 | - presencePenalty: { | |
| 440 | - scale: request.body.presence_penalty, | |
| 441 | - applyToWhitespaces: false, | |
| 442 | - applyToPunctuations: false, | |
| 443 | - applyToNumbers: false, | |
| 444 | - applyToStopwords: false, | |
| 445 | - applyToEmojis: false, | |
| 446 | - }, | |
| 447 | - countPenalty: { | |
| 448 | - scale: request.body.count_pen, | |
| 449 | - applyToWhitespaces: false, | |
| 450 | - applyToPunctuations: false, | |
| 451 | - applyToNumbers: false, | |
| 452 | - applyToStopwords: false, | |
| 453 | - applyToEmojis: false, | |
| 454 | - }, | |
| 455 | - prompt: request.body.messages, | |
| 456 | - }), | |
| 457 | 435 | signal: controller.signal, |
| 458 | 436 | }; |
| 459 | 437 | |
| 460 | - fetch(`https://api.ai21.com/studio/v1/${request.body.model}/complete`, options) | |
| 438 | + console.log('AI21 request:', body); | |
| 461 | - .then(r => r.json()) | |
| 462 | - .then(r => { | |
| 463 | - if (r.completions === undefined) { | |
| 464 | - console.log(r); | |
| 465 | - } else { | |
| 466 | - console.log(r.completions[0].data.text); | |
| 467 | - } | |
| 468 | - const reply = { choices: [{ 'message': { 'content': r.completions?.[0]?.data?.text } }] }; | |
| 469 | - return response.send(reply); | |
| 470 | - }) | |
| 471 | - .catch(err => { | |
| 472 | - console.error(err); | |
| 473 | - return response.send({ error: true }); | |
| 474 | - }); | |
| 475 | 439 | |
| 440 | + try{ | |
| 441 | + const generateResponse = await fetch(API_AI21 + '/chat/completions', options); | |
| 442 | + if (request.body.stream) { | |
| 443 | + forwardFetchResponse(generateResponse, response); | |
| 444 | + } else { | |
| 445 | + if (!generateResponse.ok) { | |
| 446 | + console.log(`AI21 API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); | |
| 447 | + return response.status(500).send({ error: true }); | |
| 448 | + } | |
| 449 | + const generateResponseJson = await generateResponse.json(); | |
| 450 | + console.log('AI21 response:', generateResponseJson); | |
| 451 | + return response.send(generateResponseJson); | |
| 452 | + } | |
| 453 | + } catch (error) { | |
| 454 | + console.log('Error communicating with MistralAI API: ', error); | |
| 455 | + if (!response.headersSent) { | |
| 456 | + response.send({ error: true }); | |
| 457 | + } else { | |
| 458 | + response.end(); | |
| 459 | + } | |
| 460 | + } | |
| 476 | 461 | } |
| 477 | 462 | |
| 478 | 463 | /** |
| @@ -144,6 +144,7 @@ const spp_nerd_v2 = new SentencePieceTokenizer('src/tokenizers/nerdstash_v2.mode | ||
| 144 | 144 | const spp_mistral = new SentencePieceTokenizer('src/tokenizers/mistral.model'); |
| 145 | 145 | const spp_yi = new SentencePieceTokenizer('src/tokenizers/yi.model'); |
| 146 | 146 | const spp_gemma = new SentencePieceTokenizer('src/tokenizers/gemma.model'); |
| 147 | +const spp_jamba = new SentencePieceTokenizer('src/tokenizers/jamba.model'); | |
| 147 | 148 | const claude_tokenizer = new WebTokenizer('src/tokenizers/claude.json'); |
| 148 | 149 | const llama3_tokenizer = new WebTokenizer('src/tokenizers/llama3.json'); |
| 149 | 150 | |
| @@ -154,6 +155,7 @@ const sentencepieceTokenizers = [ | ||
| 154 | 155 | 'mistral', |
| 155 | 156 | 'yi', |
| 156 | 157 | 'gemma', |
| 158 | + 'jamba', | |
| 157 | 159 | ]; |
| 158 | 160 | |
| 159 | 161 | /** |
| @@ -186,6 +188,10 @@ function getSentencepiceTokenizer(model) { | ||
| 186 | 188 | return spp_gemma; |
| 187 | 189 | } |
| 188 | 190 | |
| 191 | + if (model.includes('jamba')) { | |
| 192 | + return spp_jamba; | |
| 193 | + } | |
| 194 | + | |
| 189 | 195 | return null; |
| 190 | 196 | } |
| 191 | 197 | |
| @@ -322,6 +328,10 @@ function getTokenizerModel(requestModel) { | ||
| 322 | 328 | return 'gemma'; |
| 323 | 329 | } |
| 324 | 330 | |
| 331 | + if (requestModel.includes('jamba')) { | |
| 332 | + return 'jamba'; | |
| 333 | + } | |
| 334 | + | |
| 325 | 335 | // default |
| 326 | 336 | return 'gpt-3.5-turbo'; |
| 327 | 337 | } |
| @@ -537,59 +547,13 @@ function createWebTokenizerDecodingHandler(tokenizer) { | ||
| 537 | 547 | |
| 538 | 548 | const router = express.Router(); |
| 539 | 549 | |
| 540 | -router.post('/ai21/count', jsonParser, async function (req, res) { | |
| 541 | - if (!req.body) return res.sendStatus(400); | |
| 542 | - const key = readSecret(req.user.directories, SECRET_KEYS.AI21); | |
| 543 | - const options = { | |
| 544 | - method: 'POST', | |
| 545 | - headers: { | |
| 546 | - accept: 'application/json', | |
| 547 | - 'content-type': 'application/json', | |
| 548 | - Authorization: `Bearer ${key}`, | |
| 549 | - }, | |
| 550 | - body: JSON.stringify({ text: req.body[0].content }), | |
| 551 | - }; | |
| 552 | - | |
| 553 | - try { | |
| 554 | - const response = await fetch('https://api.ai21.com/studio/v1/tokenize', options); | |
| 555 | - const data = await response.json(); | |
| 556 | - return res.send({ 'token_count': data?.tokens?.length || 0 }); | |
| 557 | - } catch (err) { | |
| 558 | - console.error(err); | |
| 559 | - return res.send({ 'token_count': 0 }); | |
| 560 | - } | |
| 561 | -}); | |
| 562 | - | |
| 563 | -router.post('/google/count', jsonParser, async function (req, res) { | |
| 564 | - if (!req.body) return res.sendStatus(400); | |
| 565 | - const options = { | |
| 566 | - method: 'POST', | |
| 567 | - headers: { | |
| 568 | - accept: 'application/json', | |
| 569 | - 'content-type': 'application/json', | |
| 570 | - }, | |
| 571 | - body: JSON.stringify({ contents: convertGooglePrompt(req.body, String(req.query.model)).contents }), | |
| 572 | - }; | |
| 573 | - try { | |
| 574 | - const reverseProxy = req.query.reverse_proxy?.toString() || ''; | |
| 575 | - const proxyPassword = req.query.proxy_password?.toString() || ''; | |
| 576 | - const apiKey = reverseProxy ? proxyPassword : readSecret(req.user.directories, SECRET_KEYS.MAKERSUITE); | |
| 577 | - const apiUrl = new URL(reverseProxy || API_MAKERSUITE); | |
| 578 | - const response = await fetch(`${apiUrl.origin}/v1beta/models/${req.query.model}:countTokens?key=${apiKey}`, options); | |
| 579 | - const data = await response.json(); | |
| 580 | - return res.send({ 'token_count': data?.totalTokens || 0 }); | |
| 581 | - } catch (err) { | |
| 582 | - console.error(err); | |
| 583 | - return res.send({ 'token_count': 0 }); | |
| 584 | - } | |
| 585 | -}); | |
| 586 | - | |
| 587 | 550 | router.post('/llama/encode', jsonParser, createSentencepieceEncodingHandler(spp_llama)); |
| 588 | 551 | router.post('/nerdstash/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd)); |
| 589 | 552 | router.post('/nerdstash_v2/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd_v2)); |
| 590 | 553 | router.post('/mistral/encode', jsonParser, createSentencepieceEncodingHandler(spp_mistral)); |
| 591 | 554 | router.post('/yi/encode', jsonParser, createSentencepieceEncodingHandler(spp_yi)); |
| 592 | 555 | router.post('/gemma/encode', jsonParser, createSentencepieceEncodingHandler(spp_gemma)); |
| 556 | +router.post('/jamba/encode', jsonParser, createSentencepieceEncodingHandler(spp_jamba)); | |
| 593 | 557 | router.post('/gpt2/encode', jsonParser, createTiktokenEncodingHandler('gpt2')); |
| 594 | 558 | router.post('/claude/encode', jsonParser, createWebTokenizerEncodingHandler(claude_tokenizer)); |
| 595 | 559 | router.post('/llama3/encode', jsonParser, createWebTokenizerEncodingHandler(llama3_tokenizer)); |
| @@ -599,6 +563,7 @@ router.post('/nerdstash_v2/decode', jsonParser, createSentencepieceDecodingHandl | ||
| 599 | 563 | router.post('/mistral/decode', jsonParser, createSentencepieceDecodingHandler(spp_mistral)); |
| 600 | 564 | router.post('/yi/decode', jsonParser, createSentencepieceDecodingHandler(spp_yi)); |
| 601 | 565 | router.post('/gemma/decode', jsonParser, createSentencepieceDecodingHandler(spp_gemma)); |
| 566 | +router.post('/jamba/decode', jsonParser, createSentencepieceDecodingHandler(spp_jamba)); | |
| 602 | 567 | router.post('/gpt2/decode', jsonParser, createTiktokenDecodingHandler('gpt2')); |
| 603 | 568 | router.post('/claude/decode', jsonParser, createWebTokenizerDecodingHandler(claude_tokenizer)); |
| 604 | 569 | router.post('/llama3/decode', jsonParser, createWebTokenizerDecodingHandler(llama3_tokenizer)); |
| @@ -637,6 +602,11 @@ router.post('/openai/encode', jsonParser, async function (req, res) { | ||
| 637 | 602 | return handler(req, res); |
| 638 | 603 | } |
| 639 | 604 | |
| 605 | + if (queryModel.includes('jamba')) { | |
| 606 | + const handler = createSentencepieceEncodingHandler(spp_jamba); | |
| 607 | + return handler(req, res); | |
| 608 | + } | |
| 609 | + | |
| 640 | 610 | const model = getTokenizerModel(queryModel); |
| 641 | 611 | const handler = createTiktokenEncodingHandler(model); |
| 642 | 612 | return handler(req, res); |
| @@ -680,6 +650,11 @@ router.post('/openai/decode', jsonParser, async function (req, res) { | ||
| 680 | 650 | return handler(req, res); |
| 681 | 651 | } |
| 682 | 652 | |
| 653 | + if (queryModel.includes('jamba')) { | |
| 654 | + const handler = createSentencepieceDecodingHandler(spp_jamba); | |
| 655 | + return handler(req, res); | |
| 656 | + } | |
| 657 | + | |
| 683 | 658 | const model = getTokenizerModel(queryModel); |
| 684 | 659 | const handler = createTiktokenDecodingHandler(model); |
| 685 | 660 | return handler(req, res); |
| @@ -731,6 +706,11 @@ router.post('/openai/count', jsonParser, async function (req, res) { | ||
| 731 | 706 | return res.send({ 'token_count': num_tokens }); |
| 732 | 707 | } |
| 733 | 708 | |
| 709 | + if (model === 'jamba') { | |
| 710 | + num_tokens = await countSentencepieceArrayTokens(spp_jamba, req.body); | |
| 711 | + return res.send({ 'token_count': num_tokens }); | |
| 712 | + } | |
| 713 | + | |
| 734 | 714 | const tokensPerName = queryModel.includes('gpt-3.5-turbo-0301') ? -1 : 1; |
| 735 | 715 | const tokensPerMessage = queryModel.includes('gpt-3.5-turbo-0301') ? 4 : 3; |
| 736 | 716 | const tokensPadding = 3; |
| @@ -368,6 +368,78 @@ function convertGooglePrompt(messages, model, useSysPrompt = false, charName = ' | ||
| 368 | 368 | } |
| 369 | 369 | |
| 370 | 370 | /** |
| 371 | + * Convert AI21 prompt. Classic: system message squash, user/assistant message merge. | |
| 372 | + * @param {object[]} messages Array of messages | |
| 373 | + * @param {string} charName Character name | |
| 374 | + * @param {string} userName User name | |
| 375 | + */ | |
| 376 | +function convertAI21Messages(messages, charName = '', userName = '') { | |
| 377 | + if (!Array.isArray(messages)) { | |
| 378 | + return []; | |
| 379 | + } | |
| 380 | + | |
| 381 | + // Collect all the system messages up until the first instance of a non-system message, and then remove them from the messages array. | |
| 382 | + let i = 0, systemPrompt = ''; | |
| 383 | + | |
| 384 | + for (i = 0; i < messages.length; i++) { | |
| 385 | + if (messages[i].role !== 'system') { | |
| 386 | + break; | |
| 387 | + } | |
| 388 | + // Append example names if not already done by the frontend (e.g. for group chats). | |
| 389 | + if (userName && messages[i].name === 'example_user') { | |
| 390 | + if (!messages[i].content.startsWith(`${userName}: `)) { | |
| 391 | + messages[i].content = `${userName}: ${messages[i].content}`; | |
| 392 | + } | |
| 393 | + } | |
| 394 | + if (charName && messages[i].name === 'example_assistant') { | |
| 395 | + if (!messages[i].content.startsWith(`${charName}: `)) { | |
| 396 | + messages[i].content = `${charName}: ${messages[i].content}`; | |
| 397 | + } | |
| 398 | + } | |
| 399 | + systemPrompt += `${messages[i].content}\n\n`; | |
| 400 | + } | |
| 401 | + | |
| 402 | + messages.splice(0, i); | |
| 403 | + | |
| 404 | + // Prevent erroring out if the messages array is empty. | |
| 405 | + if (messages.length === 0) { | |
| 406 | + messages.unshift({ | |
| 407 | + role: 'user', | |
| 408 | + content: '[Start a new chat]', | |
| 409 | + }); | |
| 410 | + } | |
| 411 | + | |
| 412 | + if (systemPrompt) { | |
| 413 | + messages.unshift({ | |
| 414 | + role: 'system', | |
| 415 | + content: systemPrompt.trim(), | |
| 416 | + }); | |
| 417 | + } | |
| 418 | + | |
| 419 | + // Doesn't support completion names, so prepend if not already done by the frontend (e.g. for group chats). | |
| 420 | + messages.forEach(msg => { | |
| 421 | + if ('name' in msg) { | |
| 422 | + if (msg.role !== 'system' && !msg.content.startsWith(`${msg.name}: `)) { | |
| 423 | + msg.content = `${msg.name}: ${msg.content}`; | |
| 424 | + } | |
| 425 | + delete msg.name; | |
| 426 | + } | |
| 427 | + }); | |
| 428 | + | |
| 429 | + // Since the messaging endpoint only supports alternating turns, we have to merge messages with the same role if they follow each other | |
| 430 | + let mergedMessages = []; | |
| 431 | + messages.forEach((message) => { | |
| 432 | + if (mergedMessages.length > 0 && mergedMessages[mergedMessages.length - 1].role === message.role) { | |
| 433 | + mergedMessages[mergedMessages.length - 1].content += '\n\n' + message.content; | |
| 434 | + } else { | |
| 435 | + mergedMessages.push(message); | |
| 436 | + } | |
| 437 | + }); | |
| 438 | + | |
| 439 | + return mergedMessages; | |
| 440 | +} | |
| 441 | + | |
| 442 | +/** | |
| 371 | 443 | * Convert a prompt from the ChatML objects to the format used by MistralAI. |
| 372 | 444 | * @param {object[]} messages Array of messages |
| 373 | 445 | * @param {string} charName Character name |
| @@ -520,4 +592,5 @@ module.exports = { | ||
| 520 | 592 | convertCohereMessages, |
| 521 | 593 | convertMistralMessages, |
| 522 | 594 | convertCohereTools, |
| 595 | + convertAI21Messages, | |
| 523 | 596 | }; |
Binary file