Merge pull request #3237 from SillyTavern/deepseek Deepseek
Signed| @@ -0,0 +1,6 @@ | ||
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 128 128" version="1.1"> | |
| 3 | +<g id="surface1"> | |
| 4 | +<path d="M 126.65625 23.902344 C 125.300781 23.242188 124.714844 24.507812 123.925781 25.152344 C 123.652344 25.359375 123.425781 25.632812 123.195312 25.878906 C 121.210938 27.996094 118.894531 29.382812 115.871094 29.214844 C 111.449219 28.96875 107.675781 30.355469 104.335938 33.738281 C 103.625 29.566406 101.269531 27.082031 97.683594 25.484375 C 95.808594 24.652344 93.910156 23.824219 92.59375 22.015625 C 91.675781 20.730469 91.425781 19.296875 90.964844 17.886719 C 90.671875 17.035156 90.378906 16.164062 89.402344 16.019531 C 88.335938 15.855469 87.921875 16.746094 87.503906 17.492188 C 85.835938 20.542969 85.1875 23.902344 85.253906 27.308594 C 85.398438 34.964844 88.628906 41.066406 95.054688 45.402344 C 95.785156 45.898438 95.972656 46.398438 95.742188 47.125 C 95.308594 48.617188 94.785156 50.070312 94.324219 51.566406 C 94.03125 52.523438 93.59375 52.726562 92.570312 52.316406 C 89.109375 50.828125 85.96875 48.691406 83.3125 46.019531 C 78.742188 41.605469 74.613281 36.730469 69.460938 32.910156 C 68.269531 32.03125 67.042969 31.191406 65.785156 30.398438 C 60.535156 25.296875 66.480469 21.105469 67.855469 20.609375 C 69.296875 20.085938 68.351562 18.304688 63.703125 18.324219 C 59.050781 18.347656 54.792969 19.898438 49.371094 21.972656 C 48.566406 22.28125 47.734375 22.527344 46.890625 22.703125 C 41.820312 21.75 36.636719 21.566406 31.515625 22.160156 C 21.460938 23.28125 13.433594 28.039062 7.53125 36.148438 C 0.4375 45.898438 -1.230469 56.980469 0.8125 68.535156 C 2.960938 80.714844 9.179688 90.800781 18.730469 98.683594 C 28.640625 106.859375 40.046875 110.863281 53.066406 110.097656 C 60.96875 109.644531 69.777344 108.582031 79.703125 100.175781 C 82.207031 101.425781 84.832031 101.921875 89.195312 102.292969 C 92.554688 102.609375 95.785156 102.132812 98.289062 101.609375 C 102.207031 100.777344 101.9375 97.148438 100.523438 96.484375 C 89.03125 91.128906 91.550781 93.3125 89.253906 91.546875 C 95.097656 84.632812 103.898438 77.457031 107.34375 54.199219 C 107.609375 52.347656 107.382812 51.183594 107.34375 49.691406 C 107.324219 48.785156 107.53125 48.425781 108.570312 48.324219 C 111.457031 48.027344 114.253906 47.164062 116.8125 45.792969 C 124.257812 41.722656 127.265625 35.046875 127.972656 27.035156 C 128.078125 25.808594 127.953125 24.542969 126.65625 23.898438 Z M 61.765625 96 C 50.625 87.242188 45.222656 84.355469 42.992188 84.480469 C 40.902344 84.609375 41.28125 86.992188 41.738281 88.550781 C 42.21875 90.085938 42.84375 91.140625 43.71875 92.492188 C 44.324219 93.382812 44.742188 94.710938 43.113281 95.707031 C 39.523438 97.925781 33.289062 94.960938 32.996094 94.816406 C 25.738281 90.539062 19.664062 84.894531 15.390625 77.179688 C 11.265625 69.75 8.863281 61.78125 8.46875 53.273438 C 8.363281 51.214844 8.964844 50.492188 11.011719 50.117188 C 13.703125 49.601562 16.457031 49.53125 19.167969 49.910156 C 30.539062 51.574219 40.214844 56.65625 48.332031 64.703125 C 52.960938 69.289062 56.464844 74.769531 60.074219 80.121094 C 63.914062 85.808594 68.042969 91.226562 73.300781 95.664062 C 75.15625 97.222656 76.632812 98.40625 78.054688 99.273438 C 73.777344 99.753906 66.640625 99.863281 61.765625 96 Z M 67.097656 61.652344 C 67.097656 61.117188 67.359375 60.609375 67.800781 60.304688 C 68.246094 60 68.808594 59.929688 69.3125 60.121094 C 70.378906 62.097656 70.207031 62.515625 69.894531 62.824219 C 69.585938 63.132812 69.164062 63.300781 68.726562 63.296875 C 68.292969 63.296875 67.875 63.125 67.570312 62.816406 C 67.265625 62.507812 67.097656 62.085938 67.105469 61.652344 Z M 83.683594 70.164062 C 82.617188 70.597656 81.558594 70.96875 80.539062 71.019531 C 79.007812 71.070312 77.503906 70.59375 76.28125 69.664062 C 74.820312 68.4375 73.777344 67.753906 73.339844 65.621094 C 73.1875 64.578125 73.214844 63.519531 73.425781 62.484375 C 73.796875 60.742188 73.382812 59.621094 72.148438 58.609375 C 71.152344 57.777344 69.878906 57.546875 68.480469 57.546875 C 68 57.519531 67.535156 57.375 67.125 57.128906 C 66.539062 56.84375 66.058594 56.117188 66.515625 55.222656 C 66.667969 54.933594 67.371094 54.230469 67.542969 54.101562 C 69.441406 53.023438 71.632812 53.375 73.652344 54.1875 C 75.53125 54.953125 76.949219 56.363281 78.992188 58.355469 C 81.078125 60.761719 81.457031 61.429688 82.644531 63.230469 C 83.585938 64.644531 84.4375 66.097656 85.019531 67.753906 C 85.375 68.792969 84.917969 69.644531 83.683594 70.164062 Z M 83.683594 70.164062 "/> | |
| 5 | +</g> | |
| 6 | +</svg> | |
| @@ -682,7 +682,7 @@ | ||
| 682 | 682 | </span> |
| 683 | 683 | </div> |
| 684 | 684 | </div> |
| 685 | 685 | <div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt,deepseek"> |
| 686 | 686 | <div class="range-block-title" data-i18n="Temperature"> |
| 687 | 687 | Temperature |
| 688 | 688 | </div> |
| @@ -695,7 +695,7 @@ | ||
| 695 | 695 | </div> |
| 696 | 696 | </div> |
| 697 | 697 | </div> |
| 698 | 698 | <div class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek"> |
| 699 | 699 | <div class="range-block-title" data-i18n="Frequency Penalty"> |
| 700 | 700 | Frequency Penalty |
| 701 | 701 | </div> |
| @@ -708,7 +708,7 @@ | ||
| 708 | 708 | </div> |
| 709 | 709 | </div> |
| 710 | 710 | </div> |
| 711 | 711 | <div class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq,mistralai,nanogpt,deepseek"> |
| 712 | 712 | <div class="range-block-title" data-i18n="Presence Penalty"> |
| 713 | 713 | Presence Penalty |
| 714 | 714 | </div> |
| @@ -734,7 +734,7 @@ | ||
| 734 | 734 | </div> |
| 735 | 735 | </div> |
| 736 | 736 | </div> |
| 737 | 737 | <div class="range-block" data-source="openai,claude,openrouter,ai21,scale,makersuite,mistralai,custom,cohere,perplexity,groq,01ai,nanogpt,deepseek"> |
| 738 | 738 | <div class="range-block-title" data-i18n="Top P"> |
| 739 | 739 | Top P |
| 740 | 740 | </div> |
| @@ -2679,6 +2679,7 @@ | ||
| 2679 | 2679 | <option value="blockentropy">Block Entropy</option> |
| 2680 | 2680 | <option value="claude">Claude</option> |
| 2681 | 2681 | <option value="cohere">Cohere</option> |
| 2682 | + <option value="deepseek">DeepSeek</option> | |
| 2682 | 2683 | <option value="groq">Groq</option> |
| 2683 | 2684 | <option value="makersuite">Google AI Studio</option> |
| 2684 | 2685 | <option value="mistralai">MistralAI</option> |
| @@ -3192,6 +3193,23 @@ | ||
| 3192 | 3193 | </select> |
| 3193 | 3194 | </div> |
| 3194 | 3195 | </div> |
| 3196 | + <div id="deepseek_form" data-source="deepseek"> | |
| 3197 | + <h4 data-i18n="DeepSeek API Key">DeepSeek API Key</h4> | |
| 3198 | + <div class="flex-container"> | |
| 3199 | + <input id="api_key_deepseek" name="api_key_deepseek" class="text_pole flex1" value="" type="text" autocomplete="off"> | |
| 3200 | + <div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_nanogpt"></div> | |
| 3201 | + </div> | |
| 3202 | + <div data-for="api_key_deepseek" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page."> | |
| 3203 | + For privacy reasons, your API key will be hidden after you reload the page. | |
| 3204 | + </div> | |
| 3205 | + <div> | |
| 3206 | + <h4 data-i18n="DeepSeek Model">DeepSeek Model</h4> | |
| 3207 | + <select id="model_deepseek_select"> | |
| 3208 | + <option value="deepseek-chat">deepseek-chat</option> | |
| 3209 | + <option value="deepseek-coder">deepseek-coder</option> | |
| 3210 | + </select> | |
| 3211 | + </div> | |
| 3212 | + </div> | |
| 3195 | 3213 | <div id="perplexity_form" data-source="perplexity"> |
| 3196 | 3214 | <h4 data-i18n="Perplexity API Key">Perplexity API Key</h4> |
| 3197 | 3215 | <div class="flex-container"> |
| @@ -3311,8 +3329,9 @@ | ||
| 3311 | 3329 | <h4 data-i18n="Prompt Post-Processing">Prompt Post-Processing</h4> |
| 3312 | 3330 | <select id="custom_prompt_post_processing" class="text_pole" title="Applies additional processing to the prompt before sending it to the API." data-i18n="[title]Applies additional processing to the prompt before sending it to the API."> |
| 3313 | 3331 | <option data-i18n="prompt_post_processing_none" value="">None</option> |
| 3314 | 3332 | <option data-i18n="prompt_post_processing_merge" value="merge">Merge consecutive roles</option> |
| 3315 | 3333 | <option data-i18n="prompt_post_processing_semi" value="strictsemi">StrictSemi-strict (user first, alternating roles)</option> |
| 3334 | + <option data-i18n="prompt_post_processing_strict" value="strict">Strict (user first, alternating roles)</option> | |
| 3316 | 3335 | </select> |
| 3317 | 3336 | </form> |
| 3318 | 3337 | <div id="01ai_form" data-source="01ai"> |
| @@ -3762,6 +3781,7 @@ | ||
| 3762 | 3781 | <option value="17">Mistral Nemo</option> |
| 3763 | 3782 | <option value="8">Yi</option> |
| 3764 | 3783 | <option value="11">Claude 1/2</option> |
| 3784 | + <option value="18">DeepSeek V3</option> | |
| 3765 | 3785 | <option value="6">API (WebUI / koboldcpp)</option> |
| 3766 | 3786 | </select> |
| 3767 | 3787 | </div> |
| @@ -390,6 +390,7 @@ function RA_autoconnect(PrevApi) { | ||
| 390 | 390 | || (secret_state[SECRET_KEYS.ZEROONEAI] && oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI) |
| 391 | 391 | || (secret_state[SECRET_KEYS.BLOCKENTROPY] && oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) |
| 392 | 392 | || (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) |
| 393 | + || (secret_state[SECRET_KEYS.DEEPSEEK] && oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) | |
| 393 | 394 | || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) |
| 394 | 395 | ) { |
| 395 | 396 | $('#api_button_openai').trigger('click'); |
| @@ -183,6 +183,7 @@ export const chat_completion_sources = { | ||
| 183 | 183 | ZEROONEAI: '01ai', |
| 184 | 184 | BLOCKENTROPY: 'blockentropy', |
| 185 | 185 | NANOGPT: 'nanogpt', |
| 186 | + DEEPSEEK: 'deepseek', | |
| 186 | 187 | }; |
| 187 | 188 | |
| 188 | 189 | const character_names_behavior = { |
| @@ -204,6 +205,7 @@ const custom_prompt_post_processing_types = { | ||
| 204 | 205 | /** @deprecated Use MERGE instead. */ |
| 205 | 206 | CLAUDE: 'claude', |
| 206 | 207 | MERGE: 'merge', |
| 208 | + SEMI: 'semi', | |
| 207 | 209 | STRICT: 'strict', |
| 208 | 210 | }; |
| 209 | 211 | |
| @@ -261,6 +263,7 @@ const default_settings = { | ||
| 261 | 263 | nanogpt_model: 'gpt-4o-mini', |
| 262 | 264 | zerooneai_model: 'yi-large', |
| 263 | 265 | blockentropy_model: 'be-70b-base-llama3.1', |
| 266 | + deepseek_model: 'deepseek-chat', | |
| 264 | 267 | custom_model: '', |
| 265 | 268 | custom_url: '', |
| 266 | 269 | custom_include_body: '', |
| @@ -339,6 +342,7 @@ const oai_settings = { | ||
| 339 | 342 | nanogpt_model: 'gpt-4o-mini', |
| 340 | 343 | zerooneai_model: 'yi-large', |
| 341 | 344 | blockentropy_model: 'be-70b-base-llama3.1', |
| 345 | + deepseek_model: 'deepseek-chat', | |
| 342 | 346 | custom_model: '', |
| 343 | 347 | custom_url: '', |
| 344 | 348 | custom_include_body: '', |
| @@ -1523,6 +1527,8 @@ function getChatCompletionModel() { | ||
| 1523 | 1527 | return oai_settings.blockentropy_model; |
| 1524 | 1528 | case chat_completion_sources.NANOGPT: |
| 1525 | 1529 | return oai_settings.nanogpt_model; |
| 1530 | + case chat_completion_sources.DEEPSEEK: | |
| 1531 | + return oai_settings.deepseek_model; | |
| 1526 | 1532 | default: |
| 1527 | 1533 | throw new Error(`Unknown chat completion source: ${oai_settings.chat_completion_source}`); |
| 1528 | 1534 | } |
| @@ -1698,6 +1704,24 @@ function saveModelList(data) { | ||
| 1698 | 1704 | |
| 1699 | 1705 | $('#model_nanogpt_select').val(oai_settings.nanogpt_model).trigger('change'); |
| 1700 | 1706 | } |
| 1707 | + | |
| 1708 | + if (oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) { | |
| 1709 | + $('#model_deepseek_select').empty(); | |
| 1710 | + model_list.forEach((model) => { | |
| 1711 | + $('#model_deepseek_select').append( | |
| 1712 | + $('<option>', { | |
| 1713 | + value: model.id, | |
| 1714 | + text: model.id, | |
| 1715 | + })); | |
| 1716 | + }); | |
| 1717 | + | |
| 1718 | + const selectedModel = model_list.find(model => model.id === oai_settings.deepseek_model); | |
| 1719 | + if (model_list.length > 0 && (!selectedModel || !oai_settings.deepseek_model)) { | |
| 1720 | + oai_settings.deepseek_model = model_list[0].id; | |
| 1721 | + } | |
| 1722 | + | |
| 1723 | + $('#model_deepseek_select').val(oai_settings.deepseek_model).trigger('change'); | |
| 1724 | + } | |
| 1701 | 1725 | } |
| 1702 | 1726 | |
| 1703 | 1727 | function appendOpenRouterOptions(model_list, groupModels = false, sort = false) { |
| @@ -1838,6 +1862,7 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1838 | 1862 | const isGroq = oai_settings.chat_completion_source == chat_completion_sources.GROQ; |
| 1839 | 1863 | const is01AI = oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI; |
| 1840 | 1864 | const isNano = oai_settings.chat_completion_source == chat_completion_sources.NANOGPT; |
| 1865 | + const isDeepSeek = oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK; | |
| 1841 | 1866 | const isTextCompletion = isOAI && textCompletionModels.includes(oai_settings.openai_model); |
| 1842 | 1867 | const isQuiet = type === 'quiet'; |
| 1843 | 1868 | const isImpersonate = type === 'impersonate'; |
| @@ -1902,7 +1927,7 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 1902 | 1927 | } |
| 1903 | 1928 | |
| 1904 | 1929 | // Add logprobs request (currently OpenAI only, max 5 on their side) |
| 1905 | 1930 | if (useLogprobs && (isOAI || isCustom || isDeepSeek)) { |
| 1906 | 1931 | generate_data['logprobs'] = 5; |
| 1907 | 1932 | } |
| 1908 | 1933 | |
| @@ -2000,6 +2025,11 @@ async function sendOpenAIRequest(type, messages, signal) { | ||
| 2000 | 2025 | delete generate_data.stop; |
| 2001 | 2026 | } |
| 2002 | 2027 | |
| 2028 | + // https://api-docs.deepseek.com/api/create-chat-completion | |
| 2029 | + if (isDeepSeek) { | |
| 2030 | + generate_data.top_p = generate_data.top_p || Number.EPSILON; | |
| 2031 | + } | |
| 2032 | + | |
| 2003 | 2033 | if ((isOAI || isOpenRouter || isMistral || isCustom || isCohere || isNano) && oai_settings.seed >= 0) { |
| 2004 | 2034 | generate_data['seed'] = oai_settings.seed; |
| 2005 | 2035 | } |
| @@ -2122,6 +2152,7 @@ function parseChatCompletionLogprobs(data) { | ||
| 2122 | 2152 | |
| 2123 | 2153 | switch (oai_settings.chat_completion_source) { |
| 2124 | 2154 | case chat_completion_sources.OPENAI: |
| 2155 | + case chat_completion_sources.DEEPSEEK: | |
| 2125 | 2156 | case chat_completion_sources.CUSTOM: |
| 2126 | 2157 | if (!data.choices?.length) { |
| 2127 | 2158 | return null; |
| @@ -3041,6 +3072,7 @@ function loadOpenAISettings(data, settings) { | ||
| 3041 | 3072 | oai_settings.perplexity_model = settings.perplexity_model ?? default_settings.perplexity_model; |
| 3042 | 3073 | oai_settings.groq_model = settings.groq_model ?? default_settings.groq_model; |
| 3043 | 3074 | oai_settings.nanogpt_model = settings.nanogpt_model ?? default_settings.nanogpt_model; |
| 3075 | + oai_settings.deepseek_model = settings.deepseek_model ?? default_settings.deepseek_model; | |
| 3044 | 3076 | oai_settings.blockentropy_model = settings.blockentropy_model ?? default_settings.blockentropy_model; |
| 3045 | 3077 | oai_settings.zerooneai_model = settings.zerooneai_model ?? default_settings.zerooneai_model; |
| 3046 | 3078 | oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model; |
| @@ -3122,6 +3154,8 @@ function loadOpenAISettings(data, settings) { | ||
| 3122 | 3154 | $(`#model_groq_select option[value="${oai_settings.groq_model}"`).attr('selected', true); |
| 3123 | 3155 | $('#model_nanogpt_select').val(oai_settings.nanogpt_model); |
| 3124 | 3156 | $(`#model_nanogpt_select option[value="${oai_settings.nanogpt_model}"`).attr('selected', true); |
| 3157 | + $('#model_deepseek_select').val(oai_settings.deepseek_model); | |
| 3158 | + $(`#model_deepseek_select option[value="${oai_settings.deepseek_model}"`).prop('selected', true); | |
| 3125 | 3159 | $('#model_01ai_select').val(oai_settings.zerooneai_model); |
| 3126 | 3160 | $('#model_blockentropy_select').val(oai_settings.blockentropy_model); |
| 3127 | 3161 | $('#custom_model_id').val(oai_settings.custom_model); |
| @@ -3861,6 +3895,7 @@ function onSettingsPresetChange() { | ||
| 3861 | 3895 | perplexity_model: ['#model_perplexity_select', 'perplexity_model', false], |
| 3862 | 3896 | groq_model: ['#model_groq_select', 'groq_model', false], |
| 3863 | 3897 | nanogpt_model: ['#model_nanogpt_select', 'nanogpt_model', false], |
| 3898 | + deepseek_model: ['#model_deepseek_select', 'deepseek_model', false], | |
| 3864 | 3899 | zerooneai_model: ['#model_01ai_select', 'zerooneai_model', false], |
| 3865 | 3900 | blockentropy_model: ['#model_blockentropy_select', 'blockentropy_model', false], |
| 3866 | 3901 | custom_model: ['#custom_model_id', 'custom_model', false], |
| @@ -4120,6 +4155,16 @@ async function onModelChange() { | ||
| 4120 | 4155 | oai_settings.nanogpt_model = value; |
| 4121 | 4156 | } |
| 4122 | 4157 | |
| 4158 | + if ($(this).is('#model_deepseek_select')) { | |
| 4159 | + if (!value) { | |
| 4160 | + console.debug('Null DeepSeek model selected. Ignoring.'); | |
| 4161 | + return; | |
| 4162 | + } | |
| 4163 | + | |
| 4164 | + console.log('DeepSeek model changed to', value); | |
| 4165 | + oai_settings.deepseek_model = value; | |
| 4166 | + } | |
| 4167 | + | |
| 4123 | 4168 | if (value && $(this).is('#model_01ai_select')) { |
| 4124 | 4169 | console.log('01.AI model changed to', value); |
| 4125 | 4170 | oai_settings.zerooneai_model = value; |
| @@ -4436,6 +4481,22 @@ async function onModelChange() { | ||
| 4436 | 4481 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4437 | 4482 | } |
| 4438 | 4483 | |
| 4484 | + if (oai_settings.chat_completion_source === chat_completion_sources.DEEPSEEK) { | |
| 4485 | + if (oai_settings.max_context_unlocked) { | |
| 4486 | + $('#openai_max_context').attr('max', unlocked_max); | |
| 4487 | + } else if (oai_settings.deepseek_model == 'deepseek-chat') { | |
| 4488 | + $('#openai_max_context').attr('max', max_64k); | |
| 4489 | + } else if (oai_settings.deepseek_model == 'deepseek-coder') { | |
| 4490 | + $('#openai_max_context').attr('max', max_16k); | |
| 4491 | + } else { | |
| 4492 | + $('#openai_max_context').attr('max', max_64k); | |
| 4493 | + } | |
| 4494 | + | |
| 4495 | + oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context); | |
| 4496 | + $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); | |
| 4497 | + $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | |
| 4498 | + } | |
| 4499 | + | |
| 4439 | 4500 | if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) { |
| 4440 | 4501 | oai_settings.pres_pen_openai = Math.min(Math.max(0, oai_settings.pres_pen_openai), 1); |
| 4441 | 4502 | $('#pres_pen_openai').attr('max', 1).attr('min', 0).val(oai_settings.pres_pen_openai).trigger('input'); |
| @@ -4653,6 +4714,19 @@ async function onConnectButtonClick(e) { | ||
| 4653 | 4714 | } |
| 4654 | 4715 | } |
| 4655 | 4716 | |
| 4717 | + if (oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) { | |
| 4718 | + const api_key_deepseek = String($('#api_key_deepseek').val()).trim(); | |
| 4719 | + | |
| 4720 | + if (api_key_deepseek.length) { | |
| 4721 | + await writeSecret(SECRET_KEYS.DEEPSEEK, api_key_deepseek); | |
| 4722 | + } | |
| 4723 | + | |
| 4724 | + if (!secret_state[SECRET_KEYS.DEEPSEEK]) { | |
| 4725 | + console.log('No secret key saved for DeepSeek'); | |
| 4726 | + return; | |
| 4727 | + } | |
| 4728 | + } | |
| 4729 | + | |
| 4656 | 4730 | if (oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI) { |
| 4657 | 4731 | const api_key_01ai = String($('#api_key_01ai').val()).trim(); |
| 4658 | 4732 | |
| @@ -4734,6 +4808,9 @@ function toggleChatCompletionForms() { | ||
| 4734 | 4808 | else if (oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY) { |
| 4735 | 4809 | $('#model_blockentropy_select').trigger('change'); |
| 4736 | 4810 | } |
| 4811 | + else if (oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) { | |
| 4812 | + $('#model_deepseek_select').trigger('change'); | |
| 4813 | + } | |
| 4737 | 4814 | $('[data-source]').each(function () { |
| 4738 | 4815 | const validSources = $(this).data('source').split(','); |
| 4739 | 4816 | $(this).toggle(validSources.includes(oai_settings.chat_completion_source)); |
| @@ -5447,6 +5524,7 @@ export function initOpenAI() { | ||
| 5447 | 5524 | $('#model_perplexity_select').on('change', onModelChange); |
| 5448 | 5525 | $('#model_groq_select').on('change', onModelChange); |
| 5449 | 5526 | $('#model_nanogpt_select').on('change', onModelChange); |
| 5527 | + $('#model_deepseek_select').on('change', onModelChange); | |
| 5450 | 5528 | $('#model_01ai_select').on('change', onModelChange); |
| 5451 | 5529 | $('#model_blockentropy_select').on('change', onModelChange); |
| 5452 | 5530 | $('#model_custom_select').on('change', onModelChange); |
| @@ -39,6 +39,7 @@ export const SECRET_KEYS = { | ||
| 39 | 39 | TAVILY: 'api_key_tavily', |
| 40 | 40 | BFL: 'api_key_bfl', |
| 41 | 41 | GENERIC: 'api_key_generic', |
| 42 | + DEEPSEEK: 'api_key_deepseek', | |
| 42 | 43 | }; |
| 43 | 44 | |
| 44 | 45 | const INPUT_MAP = { |
| @@ -73,6 +74,7 @@ const INPUT_MAP = { | ||
| 73 | 74 | [SECRET_KEYS.BLOCKENTROPY]: '#api_key_blockentropy', |
| 74 | 75 | [SECRET_KEYS.NANOGPT]: '#api_key_nanogpt', |
| 75 | 76 | [SECRET_KEYS.GENERIC]: '#api_key_generic', |
| 77 | + [SECRET_KEYS.DEEPSEEK]: '#api_key_deepseek', | |
| 76 | 78 | }; |
| 77 | 79 | |
| 78 | 80 | async function clearSecret() { |
| @@ -3815,6 +3815,7 @@ function getModelOptions(quiet) { | ||
| 3815 | 3815 | { id: 'model_nanogpt_select', api: 'openai', type: chat_completion_sources.NANOGPT }, |
| 3816 | 3816 | { id: 'model_01ai_select', api: 'openai', type: chat_completion_sources.ZEROONEAI }, |
| 3817 | 3817 | { id: 'model_blockentropy_select', api: 'openai', type: chat_completion_sources.BLOCKENTROPY }, |
| 3818 | + { id: 'model_deepseek_select', api: 'openai', type: chat_completion_sources.DEEPSEEK }, | |
| 3818 | 3819 | { id: 'model_novel_select', api: 'novel', type: null }, |
| 3819 | 3820 | { id: 'horde_model', api: 'koboldhorde', type: null }, |
| 3820 | 3821 | ]; |
| @@ -31,6 +31,7 @@ export const tokenizers = { | ||
| 31 | 31 | QWEN2: 15, |
| 32 | 32 | COMMAND_R: 16, |
| 33 | 33 | NEMO: 17, |
| 34 | + DEEPSEEK: 18, | |
| 34 | 35 | BEST_MATCH: 99, |
| 35 | 36 | MANUAL_SELECTION: 411, |
| 36 | 37 | }; |
| @@ -46,6 +47,7 @@ export const ENCODE_TOKENIZERS = [ | ||
| 46 | 47 | tokenizers.QWEN2, |
| 47 | 48 | tokenizers.COMMAND_R, |
| 48 | 49 | tokenizers.NEMO, |
| 50 | + tokenizers.DEEPSEEK, | |
| 49 | 51 | // uncomment when NovelAI releases Kayra and Clio weights, lol |
| 50 | 52 | //tokenizers.NERD, |
| 51 | 53 | //tokenizers.NERD2, |
| @@ -133,6 +135,11 @@ const TOKENIZER_URLS = { | ||
| 133 | 135 | decode: '/api/tokenizers/nemo/decode', |
| 134 | 136 | count: '/api/tokenizers/nemo/encode', |
| 135 | 137 | }, |
| 138 | + [tokenizers.DEEPSEEK]: { | |
| 139 | + encode: '/api/tokenizers/deepseek/encode', | |
| 140 | + decode: '/api/tokenizers/deepseek/decode', | |
| 141 | + count: '/api/tokenizers/deepseek/encode', | |
| 142 | + }, | |
| 136 | 143 | [tokenizers.API_TEXTGENERATIONWEBUI]: { |
| 137 | 144 | encode: '/api/tokenizers/remote/textgenerationwebui/encode', |
| 138 | 145 | count: '/api/tokenizers/remote/textgenerationwebui/encode', |
| @@ -551,12 +558,17 @@ export function getTokenizerModel() { | ||
| 551 | 558 | const qwen2Tokenizer = 'qwen2'; |
| 552 | 559 | const commandRTokenizer = 'command-r'; |
| 553 | 560 | const nemoTokenizer = 'nemo'; |
| 561 | + const deepseekTokenizer = 'deepseek'; | |
| 554 | 562 | |
| 555 | 563 | // Assuming no one would use it for different models.. right? |
| 556 | 564 | if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) { |
| 557 | 565 | return gpt4Tokenizer; |
| 558 | 566 | } |
| 559 | 567 | |
| 568 | + if (oai_settings.chat_completion_source == chat_completion_sources.DEEPSEEK) { | |
| 569 | + return deepseekTokenizer; | |
| 570 | + } | |
| 571 | + | |
| 560 | 572 | // Select correct tokenizer for WindowAI proxies |
| 561 | 573 | if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI && oai_settings.windowai_model) { |
| 562 | 574 | if (oai_settings.windowai_model.includes('gpt-4')) { |
| @@ -619,6 +631,9 @@ export function getTokenizerModel() { | ||
| 619 | 631 | else if (oai_settings.openrouter_model.includes('jamba')) { |
| 620 | 632 | return jambaTokenizer; |
| 621 | 633 | } |
| 634 | + else if (oai_settings.openrouter_model.includes('deepseek')) { | |
| 635 | + return deepseekTokenizer; | |
| 636 | + } | |
| 622 | 637 | } |
| 623 | 638 | |
| 624 | 639 | if (oai_settings.chat_completion_source == chat_completion_sources.COHERE) { |
| @@ -175,6 +175,7 @@ export const CHAT_COMPLETION_SOURCES = { | ||
| 175 | 175 | ZEROONEAI: '01ai', |
| 176 | 176 | BLOCKENTROPY: 'blockentropy', |
| 177 | 177 | NANOGPT: 'nanogpt', |
| 178 | + DEEPSEEK: 'deepseek', | |
| 178 | 179 | }; |
| 179 | 180 | |
| 180 | 181 | /** |
| @@ -51,6 +51,7 @@ const API_01AI = 'https://api.01.ai/v1'; | ||
| 51 | 51 | const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1'; |
| 52 | 52 | const API_AI21 = 'https://api.ai21.com/studio/v1'; |
| 53 | 53 | const API_NANOGPT = 'https://nano-gpt.com/api/v1'; |
| 54 | +const API_DEEPSEEK = 'https://api.deepseek.com/beta'; | |
| 54 | 55 | |
| 55 | 56 | /** |
| 56 | 57 | * Applies a post-processing step to the generated messages. |
| @@ -63,9 +64,13 @@ function postProcessPrompt(messages, type, names) { | ||
| 63 | 64 | switch (type) { |
| 64 | 65 | case 'merge': |
| 65 | 66 | case 'claude': |
| 66 | 67 | return mergeMessages(messages, names, false, false); |
| 68 | + case 'semi': | |
| 69 | + return mergeMessages(messages, names, true, false); | |
| 67 | 70 | case 'strict': |
| 68 | 71 | return mergeMessages(messages, names, true, true); |
| 72 | + case 'deepseek': | |
| 73 | + return (x => x.length && (x[x.length - 1].role !== 'assistant' || (x[x.length - 1].prefix = true)) ? x : x)(mergeMessages(messages, names, true, false)); | |
| 69 | 74 | default: |
| 70 | 75 | return messages; |
| 71 | 76 | } |
| @@ -668,6 +673,10 @@ router.post('/status', jsonParser, async function (request, response_getstatus_o | ||
| 668 | 673 | api_url = API_NANOGPT; |
| 669 | 674 | api_key_openai = readSecret(request.user.directories, SECRET_KEYS.NANOGPT); |
| 670 | 675 | headers = {}; |
| 676 | + } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.DEEPSEEK) { | |
| 677 | + api_url = API_DEEPSEEK.replace('/beta', ''); | |
| 678 | + api_key_openai = readSecret(request.user.directories, SECRET_KEYS.DEEPSEEK); | |
| 679 | + headers = {}; | |
| 671 | 680 | } else { |
| 672 | 681 | console.log('This chat completion source is not supported yet.'); |
| 673 | 682 | return response_getstatus_openai.status(400).send({ error: true }); |
| @@ -939,6 +948,18 @@ router.post('/generate', jsonParser, function (request, response) { | ||
| 939 | 948 | apiKey = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); |
| 940 | 949 | headers = {}; |
| 941 | 950 | bodyParams = {}; |
| 951 | + } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.DEEPSEEK) { | |
| 952 | + apiUrl = API_DEEPSEEK; | |
| 953 | + apiKey = readSecret(request.user.directories, SECRET_KEYS.DEEPSEEK); | |
| 954 | + headers = {}; | |
| 955 | + bodyParams = {}; | |
| 956 | + | |
| 957 | + if (request.body.logprobs > 0) { | |
| 958 | + bodyParams['top_logprobs'] = request.body.logprobs; | |
| 959 | + bodyParams['logprobs'] = true; | |
| 960 | + } | |
| 961 | + | |
| 962 | + request.body.messages = postProcessPrompt(request.body.messages, 'deepseek', getPromptNames(request)); | |
| 942 | 963 | } else { |
| 943 | 964 | console.log('This chat completion source is not supported yet.'); |
| 944 | 965 | return response.status(400).send({ error: true }); |
| @@ -51,6 +51,7 @@ export const SECRET_KEYS = { | ||
| 51 | 51 | NANOGPT: 'api_key_nanogpt', |
| 52 | 52 | BFL: 'api_key_bfl', |
| 53 | 53 | GENERIC: 'api_key_generic', |
| 54 | + DEEPSEEK: 'api_key_deepseek', | |
| 54 | 55 | }; |
| 55 | 56 | |
| 56 | 57 | // These are the keys that are safe to expose, even if allowKeysExposure is false |
| @@ -226,6 +226,7 @@ const llama3_tokenizer = new WebTokenizer('src/tokenizers/llama3.json'); | ||
| 226 | 226 | const commandTokenizer = new WebTokenizer('https://github.com/SillyTavern/SillyTavern-Tokenizers/raw/main/command-r.json', 'src/tokenizers/llama3.json'); |
| 227 | 227 | const qwen2Tokenizer = new WebTokenizer('https://github.com/SillyTavern/SillyTavern-Tokenizers/raw/main/qwen2.json', 'src/tokenizers/llama3.json'); |
| 228 | 228 | const nemoTokenizer = new WebTokenizer('https://github.com/SillyTavern/SillyTavern-Tokenizers/raw/main/nemo.json', 'src/tokenizers/llama3.json'); |
| 229 | +const deepseekTokenizer = new WebTokenizer('https://github.com/SillyTavern/SillyTavern-Tokenizers/raw/main/deepseek.json', 'src/tokenizers/llama3.json'); | |
| 229 | 230 | |
| 230 | 231 | export const sentencepieceTokenizers = [ |
| 231 | 232 | 'llama', |
| @@ -407,6 +408,10 @@ export function getTokenizerModel(requestModel) { | ||
| 407 | 408 | return 'yi'; |
| 408 | 409 | } |
| 409 | 410 | |
| 411 | + if (requestModel.includes('deepseek')) { | |
| 412 | + return 'deepseek'; | |
| 413 | + } | |
| 414 | + | |
| 410 | 415 | if (requestModel.includes('gemma') || requestModel.includes('gemini')) { |
| 411 | 416 | return 'gemma'; |
| 412 | 417 | } |
| @@ -655,6 +660,7 @@ router.post('/llama3/encode', jsonParser, createWebTokenizerEncodingHandler(llam | ||
| 655 | 660 | router.post('/qwen2/encode', jsonParser, createWebTokenizerEncodingHandler(qwen2Tokenizer)); |
| 656 | 661 | router.post('/command-r/encode', jsonParser, createWebTokenizerEncodingHandler(commandTokenizer)); |
| 657 | 662 | router.post('/nemo/encode', jsonParser, createWebTokenizerEncodingHandler(nemoTokenizer)); |
| 663 | +router.post('/deepseek/encode', jsonParser, createWebTokenizerEncodingHandler(deepseekTokenizer)); | |
| 658 | 664 | router.post('/llama/decode', jsonParser, createSentencepieceDecodingHandler(spp_llama)); |
| 659 | 665 | router.post('/nerdstash/decode', jsonParser, createSentencepieceDecodingHandler(spp_nerd)); |
| 660 | 666 | router.post('/nerdstash_v2/decode', jsonParser, createSentencepieceDecodingHandler(spp_nerd_v2)); |
| @@ -668,6 +674,7 @@ router.post('/llama3/decode', jsonParser, createWebTokenizerDecodingHandler(llam | ||
| 668 | 674 | router.post('/qwen2/decode', jsonParser, createWebTokenizerDecodingHandler(qwen2Tokenizer)); |
| 669 | 675 | router.post('/command-r/decode', jsonParser, createWebTokenizerDecodingHandler(commandTokenizer)); |
| 670 | 676 | router.post('/nemo/decode', jsonParser, createWebTokenizerDecodingHandler(nemoTokenizer)); |
| 677 | +router.post('/deepseek/decode', jsonParser, createWebTokenizerDecodingHandler(deepseekTokenizer)); | |
| 671 | 678 | |
| 672 | 679 | router.post('/openai/encode', jsonParser, async function (req, res) { |
| 673 | 680 | try { |
| @@ -723,6 +730,11 @@ router.post('/openai/encode', jsonParser, async function (req, res) { | ||
| 723 | 730 | return handler(req, res); |
| 724 | 731 | } |
| 725 | 732 | |
| 733 | + if (queryModel.includes('deepseek')) { | |
| 734 | + const handler = createWebTokenizerEncodingHandler(deepseekTokenizer); | |
| 735 | + return handler(req, res); | |
| 736 | + } | |
| 737 | + | |
| 726 | 738 | const model = getTokenizerModel(queryModel); |
| 727 | 739 | const handler = createTiktokenEncodingHandler(model); |
| 728 | 740 | return handler(req, res); |
| @@ -786,6 +798,11 @@ router.post('/openai/decode', jsonParser, async function (req, res) { | ||
| 786 | 798 | return handler(req, res); |
| 787 | 799 | } |
| 788 | 800 | |
| 801 | + if (queryModel.includes('deepseek')) { | |
| 802 | + const handler = createWebTokenizerDecodingHandler(deepseekTokenizer); | |
| 803 | + return handler(req, res); | |
| 804 | + } | |
| 805 | + | |
| 789 | 806 | const model = getTokenizerModel(queryModel); |
| 790 | 807 | const handler = createTiktokenDecodingHandler(model); |
| 791 | 808 | return handler(req, res); |
| @@ -863,6 +880,13 @@ router.post('/openai/count', jsonParser, async function (req, res) { | ||
| 863 | 880 | return res.send({ 'token_count': num_tokens }); |
| 864 | 881 | } |
| 865 | 882 | |
| 883 | + if (model === 'deepseek') { | |
| 884 | + const instance = await deepseekTokenizer.get(); | |
| 885 | + if (!instance) throw new Error('Failed to load the DeepSeek tokenizer'); | |
| 886 | + num_tokens = countWebTokenizerTokens(instance, req.body); | |
| 887 | + return res.send({ 'token_count': num_tokens }); | |
| 888 | + } | |
| 889 | + | |
| 866 | 890 | const tokensPerName = queryModel.includes('gpt-3.5-turbo-0301') ? -1 : 1; |
| 867 | 891 | const tokensPerMessage = queryModel.includes('gpt-3.5-turbo-0301') ? 4 : 3; |
| 868 | 892 | const tokensPadding = 3; |
| @@ -639,9 +639,10 @@ export function convertMistralMessages(messages, names) { | ||
| 639 | 639 | * @param {any[]} messages Messages to merge |
| 640 | 640 | * @param {PromptNames} names Prompt names |
| 641 | 641 | * @param {boolean} strict Enable strict mode: only allow one system message at the start, force user first message |
| 642 | + * @param {boolean} placeholders Add user placeholders to the messages in strict mode | |
| 642 | 643 | * @returns {any[]} Merged messages |
| 643 | 644 | */ |
| 644 | 645 | export function mergeMessages(messages, names, strict, placeholders) { |
| 645 | 646 | let mergedMessages = []; |
| 646 | 647 | |
| 647 | 648 | /** @type {Map<string,object>} */ |
| @@ -700,9 +701,9 @@ export function mergeMessages(messages, names, strict) { | ||
| 700 | 701 | } |
| 701 | 702 | }); |
| 702 | 703 | |
| 703 | 704 | // Prevent erroring out if the messagesmergedMessages array is empty. |
| 704 | 705 | if (messagesmergedMessages.length === 0) { |
| 705 | 706 | messagesmergedMessages.unshift({ |
| 706 | 707 | role: 'user', |
| 707 | 708 | content: PROMPT_PLACEHOLDER, |
| 708 | 709 | }); |
| @@ -741,7 +742,7 @@ export function mergeMessages(messages, names, strict) { | ||
| 741 | 742 | mergedMessages[i].role = 'user'; |
| 742 | 743 | } |
| 743 | 744 | } |
| 744 | 745 | if (mergedMessages.length && placeholders) { |
| 745 | 746 | if (mergedMessages[0].role === 'system' && (mergedMessages.length === 1 || mergedMessages[1].role !== 'user')) { |
| 746 | 747 | mergedMessages.splice(1, 0, { role: 'user', content: PROMPT_PLACEHOLDER }); |
| 747 | 748 | } |
| @@ -749,7 +750,7 @@ export function mergeMessages(messages, names, strict) { | ||
| 749 | 750 | mergedMessages.unshift({ role: 'user', content: PROMPT_PLACEHOLDER }); |
| 750 | 751 | } |
| 751 | 752 | } |
| 752 | 753 | return mergeMessages(mergedMessages, names, false, placeholders); |
| 753 | 754 | } |
| 754 | 755 | |
| 755 | 756 | return mergedMessages; |