Merge branch 'staging' into optimize-chat-manager

8c568bfa13fa67bfe5732fcf7986ea5ed5b13a44

Cohee <18619528+Cohee1207@users.noreply.github.com>

10 files changed, +144 -0Showing whitespace changes
public/global.d.ts+2 -0
@@ -11,6 +11,7 @@ declare var SillyTavern: {
1111 libs: typeof libs;
1212};
1313
14+declare global {
1415 // Jquery plugins
1516 interface JQuery {
1617 nanogallery2(options?: any): JQuery;
@@ -109,6 +110,7 @@ interface JQuery {
109110
110111 //#endregion
111112 }
113+}
112114
113115//#region select2
114116
public/img/nanogpt.svg+43 -0
@@ -0,0 +1,43 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3+
4+<svg
5+ width="190.91216mm"
6+ height="201.47243mm"
7+ viewBox="0 0 190.91216 201.47243"
8+ version="1.1"
9+ id="svg1"
10+ xmlns="http://www.w3.org/2000/svg"
11+ xmlns:svg="http://www.w3.org/2000/svg">
12+ <defs
13+ id="defs1" />
14+ <g
15+ id="layer1"
16+ transform="translate(-2.2086436)">
17+ <g
18+ id="g8"
19+ transform="matrix(0.99583856,0,0,1.0472862,2.2086437,-7.9847956)">
20+ <path
21+ style="font-weight:bold;font-size:89.3125px;font-family:'Courier New';-inkscape-font-specification:'Courier New Bold';letter-spacing:-8.37308px;stroke-width:1.73283"
22+ d="m 161.17775,117.85719 v 23.36554 q 0,20.76935 -10.30578,39.77331 -10.21695,19.00395 -29.31819,19.00395 -11.01653,0 -18.65701,-5.60771 -7.551611,-5.71157 -14.392485,-20.8732 -6.752041,-15.26549 -6.752041,-32.29635 v -23.36554 q 0,-20.665499 10.216893,-39.669461 10.216893,-19.107806 29.318113,-19.107806 10.92769,0 18.47935,5.607725 7.64049,5.607727 14.48139,20.873203 6.92976,15.161629 6.92976,32.296339 z m -18.30165,0 q 0,-17.3424 -8.26241,-30.32325 -4.70867,-7.165428 -13.2376,-7.165428 -8.26239,0 -13.50413,7.892355 -7.906998,11.942383 -7.906998,29.596323 v 23.36554 q 0,17.44626 8.351218,30.32326 4.61983,7.16543 13.2376,7.16543 8.17356,0 13.4153,-7.89237 7.90702,-11.94237 7.90702,-29.59632 z"
23+ id="path8" />
24+ <path
25+ style="font-weight:bold;font-size:89.3125px;font-family:'Courier New';-inkscape-font-specification:'Courier New Bold';letter-spacing:-8.37308px;stroke-width:1.67461"
26+ d="M 54.800839,58.349248 V 166.67311 H 73.27526 q 6.604382,0 9.371083,2.79982 2.855949,2.70327 2.855949,7.14436 0,4.34453 -2.855949,7.14435 -2.766701,2.70327 -9.371083,2.70327 H 18.030494 q -6.604382,0 -9.4603308,-2.70327 -2.7667007,-2.79982 -2.7667007,-7.2409 0,-4.34454 2.7667007,-7.04781 2.8559488,-2.79982 9.4603308,-2.79982 H 36.504915 V 84.126852 l -16.332459,4.634176 q -3.926929,1.158544 -5.890395,1.158544 -3.480687,0 -6.0688915,-2.992905 -2.4989554,-2.992906 -2.4989554,-7.337446 0,-3.958358 1.8742165,-6.178902 1.8742167,-2.317087 7.8538604,-4.054903 z"
27+ transform="matrix(0.99545738,0,0,1.0756271,-5.6882567,-3.6821097)"
28+ id="path7" />
29+ </g>
30+ <g
31+ id="g1"
32+ transform="matrix(0.84984007,0,0,0.87855774,28.999003,5.2337341e-7)">
33+ <path
34+ style="font-weight:bold;font-size:89.3125px;font-family:'Courier New';-inkscape-font-specification:'Courier New Bold';letter-spacing:-8.37308px;stroke-width:1.73283"
35+ d="m 184.13459,37.01017 q -3.34269,3.095908 -6.12102,4.409323 -2.77834,1.266508 -5.86056,1.266508 -7.1629,0 -12.54593,-6.191815 -5.33961,-6.191816 -5.33961,-15.385722 0,-7.176877 3.68997,-13.0403372 Q 162.99318,4.3096483e-6 172.15301,4.3096483e-6 q 6.55514,0 11.46064,4.2685995903517 4.90551,4.2216915 7.20632,12.2429061 2.30081,7.974308 2.30081,16.65223 0,14.729014 -10.549,23.641474 -8.16137,6.848524 -17.88555,6.848524 -5.38303,0 -8.33501,-2.345385 -1.99693,-1.547954 -1.99693,-4.080969 0,-2.063938 1.25893,-3.424261 1.30235,-1.407231 3.16905,-1.407231 1.04187,0 2.34422,0.703615 1.69304,0.938154 3.55974,0.938154 6.72879,0 12.4157,-4.925307 5.68691,-4.972215 7.03266,-12.102184 z m -1.25893,-15.151183 q -1.43258,-6.660892 -4.25433,-9.428446 -2.77834,-2.814461 -6.38149,-2.814461 -3.77681,0 -6.42491,3.142816 -2.6481,3.095907 -2.6481,8.255753 0,5.394384 2.6481,8.72483 2.69151,3.330446 6.12102,3.330446 6.03421,0 10.93971,-11.210938 z"
36+ id="path6" />
37+ <path
38+ style="font-weight:bold;font-size:89.3125px;font-family:'Courier New';-inkscape-font-specification:'Courier New Bold';letter-spacing:-8.37308px;stroke-width:1.51638"
39+ d="m 142.10195,39.730816 h -22.30654 q -3.49058,0 -4.15545,-0.234538 -0.99731,-0.375262 -1.69543,-1.641769 -0.69812,-1.313415 -0.69812,-2.955185 0,-1.594861 0.69812,-2.908276 0.69812,-1.313416 1.72867,-1.641769 0.66488,-0.234539 4.12221,-0.234539 h 22.30654 q 3.49059,0 4.15545,0.234539 0.99732,0.375261 1.69543,1.688676 0.69812,1.266508 0.69812,2.861369 0,1.64177 -0.69812,2.955185 -0.69811,1.266507 -1.72867,1.641769 -0.66487,0.234538 -4.12221,0.234538 z"
40+ id="text2" />
41+ </g>
42+ </g>
43+</svg>
public/index.html+17 -0
@@ -2601,6 +2601,7 @@
26012601 <option value="groq">Groq</option>
26022602 <option value="makersuite">Google AI Studio</option>
26032603 <option value="mistralai">MistralAI</option>
2604+ <option value="nanogpt">NanoGPT</option>
26042605 <option value="openrouter">OpenRouter</option>
26052606 <option value="perplexity">Perplexity</option>
26062607 <option value="scale">Scale</option>
@@ -3083,6 +3084,22 @@
30833084 </optgroup>
30843085 </select>
30853086 </div>
3087+ <div id="nanogpt_form" data-source="nanogpt">
3088+ <h4 data-i18n="NanoGPT API Key">NanoGPT API Key</h4>
3089+ <div class="flex-container">
3090+ <input id="api_key_nanogpt" name="api_key_nanogpt" class="text_pole flex1" value="" type="text" autocomplete="off">
3091+ <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>
3092+ </div>
3093+ <div data-for="api_key_nanogpt" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
3094+ For privacy reasons, your API key will be hidden after you reload the page.
3095+ </div>
3096+ <div>
3097+ <h4 data-i18n="NanoGPT Model">NanoGPT Model</h4>
3098+ <select id="model_nanogpt_select">
3099+ <option value="" data-i18n="-- Connect to the API --">-- Connect to the API --</option>
3100+ </select>
3101+ </div>
3102+ </div>
30863103 <div id="perplexity_form" data-source="perplexity">
30873104 <h4 data-i18n="Perplexity API Key">Perplexity API Key</h4>
30883105 <div class="flex-container">
public/scripts/RossAscends-mods.js+1 -0
@@ -388,6 +388,7 @@ function RA_autoconnect(PrevApi) {
388388 || (secret_state[SECRET_KEYS.GROQ] && oai_settings.chat_completion_source == chat_completion_sources.GROQ)
389389 || (secret_state[SECRET_KEYS.ZEROONEAI] && oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI)
390390 || (secret_state[SECRET_KEYS.BLOCKENTROPY] && oai_settings.chat_completion_source == chat_completion_sources.BLOCKENTROPY)
391+ || (secret_state[SECRET_KEYS.NANOGPT] && oai_settings.chat_completion_source == chat_completion_sources.NANOGPT)
391392 || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM)
392393 ) {
393394 $('#api_button_openai').trigger('click');
public/scripts/openai.js+66 -0
@@ -182,6 +182,7 @@ export const chat_completion_sources = {
182182 GROQ: 'groq',
183183 ZEROONEAI: '01ai',
184184 BLOCKENTROPY: 'blockentropy',
185+ NANOGPT: 'nanogpt',
185186};
186187
187188const character_names_behavior = {
@@ -251,6 +252,7 @@ const default_settings = {
251252 cohere_model: 'command-r-plus',
252253 perplexity_model: 'llama-3.1-70b-instruct',
253254 groq_model: 'llama-3.1-70b-versatile',
255+ nanogpt_model: 'gpt-4o-mini',
254256 zerooneai_model: 'yi-large',
255257 blockentropy_model: 'be-70b-base-llama3.1',
256258 custom_model: '',
@@ -327,6 +329,7 @@ const oai_settings = {
327329 cohere_model: 'command-r-plus',
328330 perplexity_model: 'llama-3.1-70b-instruct',
329331 groq_model: 'llama-3.1-70b-versatile',
332+ nanogpt_model: 'gpt-4o-mini',
330333 zerooneai_model: 'yi-large',
331334 blockentropy_model: 'be-70b-base-llama3.1',
332335 custom_model: '',
@@ -1480,6 +1483,8 @@ function getChatCompletionModel() {
14801483 return oai_settings.zerooneai_model;
14811484 case chat_completion_sources.BLOCKENTROPY:
14821485 return oai_settings.blockentropy_model;
1486+ case chat_completion_sources.NANOGPT:
1487+ return oai_settings.nanogpt_model;
14831488 default:
14841489 throw new Error(`Unknown chat completion source: ${oai_settings.chat_completion_source}`);
14851490 }
@@ -1637,6 +1642,24 @@ function saveModelList(data) {
16371642 }
16381643 }
16391644 }
1645+
1646+ if (oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) {
1647+ $('#model_nanogpt_select').empty();
1648+ model_list.forEach((model) => {
1649+ $('#model_nanogpt_select').append(
1650+ $('<option>', {
1651+ value: model.id,
1652+ text: model.id,
1653+ }));
1654+ });
1655+
1656+ const selectedModel = model_list.find(model => model.id === oai_settings.nanogpt_model);
1657+ if (model_list.length > 0 && (!selectedModel || !oai_settings.nanogpt_model)) {
1658+ oai_settings.nanogpt_model = model_list[0].id;
1659+ }
1660+
1661+ $('#model_nanogpt_select').val(oai_settings.nanogpt_model).trigger('change');
1662+ }
16401663}
16411664
16421665function appendOpenRouterOptions(model_list, groupModels = false, sort = false) {
@@ -2961,6 +2984,7 @@ function loadOpenAISettings(data, settings) {
29612984 oai_settings.cohere_model = settings.cohere_model ?? default_settings.cohere_model;
29622985 oai_settings.perplexity_model = settings.perplexity_model ?? default_settings.perplexity_model;
29632986 oai_settings.groq_model = settings.groq_model ?? default_settings.groq_model;
2987+ oai_settings.nanogpt_model = settings.nanogpt_model ?? default_settings.nanogpt_model;
29642988 oai_settings.blockentropy_model = settings.blockentropy_model ?? default_settings.blockentropy_model;
29652989 oai_settings.zerooneai_model = settings.zerooneai_model ?? default_settings.zerooneai_model;
29662990 oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model;
@@ -3041,6 +3065,8 @@ function loadOpenAISettings(data, settings) {
30413065 $(`#model_perplexity_select option[value="${oai_settings.perplexity_model}"`).attr('selected', true);
30423066 $('#model_groq_select').val(oai_settings.groq_model);
30433067 $(`#model_groq_select option[value="${oai_settings.groq_model}"`).attr('selected', true);
3068+ $('#model_nanogpt_select').val(oai_settings.nanogpt_model);
3069+ $(`#model_nanogpt_select option[value="${oai_settings.nanogpt_model}"`).attr('selected', true);
30443070 $('#model_01ai_select').val(oai_settings.zerooneai_model);
30453071 $('#model_blockentropy_select').val(oai_settings.blockentropy_model);
30463072 $('#custom_model_id').val(oai_settings.custom_model);
@@ -3735,6 +3761,7 @@ function onSettingsPresetChange() {
37353761 cohere_model: ['#model_cohere_select', 'cohere_model', false],
37363762 perplexity_model: ['#model_perplexity_select', 'perplexity_model', false],
37373763 groq_model: ['#model_groq_select', 'groq_model', false],
3764+ nanogpt_model: ['#model_nanogpt_select', 'nanogpt_model', false],
37383765 zerooneai_model: ['#model_01ai_select', 'zerooneai_model', false],
37393766 blockentropy_model: ['#model_blockentropy_select', 'blockentropy_model', false],
37403767 custom_model: ['#custom_model_id', 'custom_model', false],
@@ -3984,6 +4011,16 @@ async function onModelChange() {
39844011 oai_settings.groq_model = value;
39854012 }
39864013
4014+ if ($(this).is('#model_nanogpt_select')) {
4015+ if (!value) {
4016+ console.debug('Null NanoGPT model selected. Ignoring.');
4017+ return;
4018+ }
4019+
4020+ console.log('NanoGPT model changed to', value);
4021+ oai_settings.nanogpt_model = value;
4022+ }
4023+
39874024 if (value && $(this).is('#model_01ai_select')) {
39884025 console.log('01.AI model changed to', value);
39894026 oai_settings.zerooneai_model = value;
@@ -4294,6 +4331,18 @@ async function onModelChange() {
42944331 $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
42954332 }
42964333
4334+ if (oai_settings.chat_completion_source === chat_completion_sources.NANOGPT) {
4335+ if (oai_settings.max_context_unlocked) {
4336+ $('#openai_max_context').attr('max', unlocked_max);
4337+ } else {
4338+ $('#openai_max_context').attr('max', max_128k);
4339+ }
4340+
4341+ oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context);
4342+ $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
4343+ $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
4344+ }
4345+
42974346 if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) {
42984347 oai_settings.pres_pen_openai = Math.min(Math.max(0, oai_settings.pres_pen_openai), 1);
42994348 $('#pres_pen_openai').attr('max', 1).attr('min', 0).val(oai_settings.pres_pen_openai).trigger('input');
@@ -4498,6 +4547,19 @@ async function onConnectButtonClick(e) {
44984547 }
44994548 }
45004549
4550+ if (oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) {
4551+ const api_key_nanogpt = String($('#api_key_nanogpt').val()).trim();
4552+
4553+ if (api_key_nanogpt.length) {
4554+ await writeSecret(SECRET_KEYS.NANOGPT, api_key_nanogpt);
4555+ }
4556+
4557+ if (!secret_state[SECRET_KEYS.NANOGPT]) {
4558+ console.log('No secret key saved for NanoGPT');
4559+ return;
4560+ }
4561+ }
4562+
45014563 if (oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI) {
45024564 const api_key_01ai = String($('#api_key_01ai').val()).trim();
45034565
@@ -4567,6 +4629,9 @@ function toggleChatCompletionForms() {
45674629 else if (oai_settings.chat_completion_source == chat_completion_sources.GROQ) {
45684630 $('#model_groq_select').trigger('change');
45694631 }
4632+ else if (oai_settings.chat_completion_source == chat_completion_sources.NANOGPT) {
4633+ $('#model_nanogpt_select').trigger('change');
4634+ }
45704635 else if (oai_settings.chat_completion_source == chat_completion_sources.ZEROONEAI) {
45714636 $('#model_01ai_select').trigger('change');
45724637 }
@@ -5288,6 +5353,7 @@ export function initOpenAI() {
52885353 $('#model_cohere_select').on('change', onModelChange);
52895354 $('#model_perplexity_select').on('change', onModelChange);
52905355 $('#model_groq_select').on('change', onModelChange);
5356+ $('#model_nanogpt_select').on('change', onModelChange);
52915357 $('#model_01ai_select').on('change', onModelChange);
52925358 $('#model_blockentropy_select').on('change', onModelChange);
52935359 $('#model_custom_select').on('change', onModelChange);
public/scripts/secrets.js+2 -0
@@ -35,6 +35,7 @@ export const SECRET_KEYS = {
3535 STABILITY: 'api_key_stability',
3636 BLOCKENTROPY: 'api_key_blockentropy',
3737 CUSTOM_OPENAI_TTS: 'api_key_custom_openai_tts',
38+ NANOGPT: 'api_key_nanogpt',
3839 TAVILY: 'api_key_tavily',
3940};
4041
@@ -68,6 +69,7 @@ const INPUT_MAP = {
6869 [SECRET_KEYS.ZEROONEAI]: '#api_key_01ai',
6970 [SECRET_KEYS.HUGGINGFACE]: '#api_key_huggingface',
7071 [SECRET_KEYS.BLOCKENTROPY]: '#api_key_blockentropy',
72+ [SECRET_KEYS.NANOGPT]: '#api_key_nanogpt',
7173};
7274
7375async function clearSecret() {
public/scripts/slash-commands.js+1 -0
@@ -3634,6 +3634,7 @@ function getModelOptions(quiet) {
36343634 { id: 'model_cohere_select', api: 'openai', type: chat_completion_sources.COHERE },
36353635 { id: 'model_perplexity_select', api: 'openai', type: chat_completion_sources.PERPLEXITY },
36363636 { id: 'model_groq_select', api: 'openai', type: chat_completion_sources.GROQ },
3637+ { id: 'model_nanogpt_select', api: 'openai', type: chat_completion_sources.NANOGPT },
36373638 { id: 'model_01ai_select', api: 'openai', type: chat_completion_sources.ZEROONEAI },
36383639 { id: 'model_blockentropy_select', api: 'openai', type: chat_completion_sources.BLOCKENTROPY },
36393640 { id: 'model_novel_select', api: 'novel', type: null },
src/constants.js+1 -0
@@ -200,6 +200,7 @@ export const CHAT_COMPLETION_SOURCES = {
200200 GROQ: 'groq',
201201 ZEROONEAI: '01ai',
202202 BLOCKENTROPY: 'blockentropy',
203+ NANOGPT: 'nanogpt',
203204};
204205
205206/**
src/endpoints/backends/chat-completions.js+10 -0
@@ -48,6 +48,7 @@ const API_MAKERSUITE = 'https://generativelanguage.googleapis.com';
4848const API_01AI = 'https://api.01.ai/v1';
4949const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1';
5050const API_AI21 = 'https://api.ai21.com/studio/v1';
51+const API_NANOGPT = 'https://nano-gpt.com/api/v1';
5152
5253/**
5354 * Applies a post-processing step to the generated messages.
@@ -656,6 +657,10 @@ router.post('/status', jsonParser, async function (request, response_getstatus_o
656657 api_url = API_BLOCKENTROPY;
657658 api_key_openai = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY);
658659 headers = {};
660+ } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.NANOGPT) {
661+ api_url = API_NANOGPT;
662+ api_key_openai = readSecret(request.user.directories, SECRET_KEYS.NANOGPT);
663+ headers = {};
659664 } else {
660665 console.log('This chat completion source is not supported yet.');
661666 return response_getstatus_openai.status(400).send({ error: true });
@@ -906,6 +911,11 @@ router.post('/generate', jsonParser, function (request, response) {
906911 apiKey = readSecret(request.user.directories, SECRET_KEYS.GROQ);
907912 headers = {};
908913 bodyParams = {};
914+ } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.NANOGPT) {
915+ apiUrl = API_NANOGPT;
916+ apiKey = readSecret(request.user.directories, SECRET_KEYS.NANOGPT);
917+ headers = {};
918+ bodyParams = {};
909919 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.ZEROONEAI) {
910920 apiUrl = API_01AI;
911921 apiKey = readSecret(request.user.directories, SECRET_KEYS.ZEROONEAI);
src/endpoints/secrets.js+1 -0
@@ -48,6 +48,7 @@ export const SECRET_KEYS = {
4848 BLOCKENTROPY: 'api_key_blockentropy',
4949 CUSTOM_OPENAI_TTS: 'api_key_custom_openai_tts',
5050 TAVILY: 'api_key_tavily',
51+ NANOGPT: 'api_key_nanogpt',
5152};
5253
5354// These are the keys that are safe to expose, even if allowKeysExposure is false