Merge branch 'staging' into hidden-reasoning-tracking

33fa5aaab812917ec8d87f5817699b8525da90b4

Wolfsblvt <wolfsblvt@gmail.com>

31 files changed, +176 -74Ignore whitespace
public/index.html+45 -36
@@ -3749,8 +3749,8 @@
37493749 </div>
37503750 <label class="checkbox_label" for="custom_stopping_strings_macro">
37513751 <input id="custom_stopping_strings_macro" type="checkbox" checked>
37523752 <small data-i18n="Replace Macro in Custom StoppingStop Strings">
37533753 Replace Macro in Custom StoppingStop Strings
37543754 </small>
37553755 </label>
37563756 </div>
@@ -3797,44 +3797,53 @@
37973797 <span data-i18n="Reasoning">Reasoning</span>
37983798 </h4>
37993799 <div>
3800- <label class="checkbox_label" for="reasoning_auto_parse" title="Automatically parse reasoning blocks from main content between the reasoning prefix/suffix. Both fields must be defined and non-empty." data-i18n="[title]reasoning_auto_parse">
3800+ <div class="flex-container alignItemsBaseline">
3801- <input id="reasoning_auto_parse" type="checkbox" />
3801+ <label class="checkbox_label flex1" for="reasoning_auto_parse" title="Automatically parse reasoning blocks from main content between the reasoning prefix/suffix. Both fields must be defined and non-empty." data-i18n="[title]reasoning_auto_parse">
3802- <small data-i18n="Auto-Parse Reasoning">
3802+ <input id="reasoning_auto_parse" type="checkbox" />
3803- Auto-Parse Reasoning
3803+ <small data-i18n="Auto-Parse">
3804- </small>
3804+ Auto-Parse
38053805 </labelsmall>
3806- <label class="checkbox_label" for="reasoning_auto_expand" title="Automatically expand reasoning blocks." data-i18n="[title]reasoning_auto_expand">
3806+ </label>
3807- <input id="reasoning_auto_expand" type="checkbox" />
3807+ <label class="checkbox_label flex1" for="reasoning_auto_expand" title="Automatically expand reasoning blocks." data-i18n="[title]reasoning_auto_expand">
3808- <small data-i18n="Auto-Expand Reasoning">
3808+ <input id="reasoning_auto_expand" type="checkbox" />
3809- Auto-Expand Reasoning
3809+ <small data-i18n="Auto-Expand">
3810- </small>
3810+ Auto-Expand
38113811 </labelsmall>
3812- <label class="checkbox_label" for="reasoning_add_to_prompts" title="Add existing reasoning blocks to prompts. To add a new reasoning block, use the message edit menu." data-i18n="[title]reasoning_add_to_prompts">
3812+ </label>
3813- <input id="reasoning_add_to_prompts" type="checkbox" />
3813+ </div>
3814- <small data-i18n="Add Reasoning to Prompts">
3814+ <div class="flex-container alignItemsBaseline">
3815- Add Reasoning to Prompts
3815+ <label class="checkbox_label flex1" for="reasoning_add_to_prompts" title="Add existing reasoning blocks to prompts. To add a new reasoning block, use the message edit menu." data-i18n="[title]reasoning_add_to_prompts">
3816- </small>
3816+ <input id="reasoning_add_to_prompts" type="checkbox" />
3817- </label>
3817+ <small data-i18n="Add to Prompts">
3818- <div class="flex-container">
3818+ Add to Prompts
3819- <div class="flex1" title="Inserted before the reasoning content." data-i18n="[title]reasoning_prefix">
3819+ </small>
3820- <small data-i18n="Prefix">Prefix</small>
3820+ </label>
3821- <textarea id="reasoning_prefix" class="text_pole textarea_compact autoSetHeight"></textarea>
3821+ <div class="flex1 flex-container alignItemsBaseline" title="Maximum number of reasoning blocks to be added per prompt, counting from the last message." data-i18n="[title]reasoning_max_additions">
3822- </div>
3822+ <input id="reasoning_max_additions" class="text_pole textarea_compact widthUnset" type="number" min="0" max="999"></textarea>
3823- <div class="flex1" title="Inserted after the reasoning content." data-i18n="[title]reasoning_suffix">
3823+ <small data-i18n="Max">Max</small>
3824- <small data-i18n="Suffix">Suffix</small>
3825- <textarea id="reasoning_suffix" class="text_pole textarea_compact autoSetHeight"></textarea>
38263824 </div>
38273825 </div>
3828- <div class="flex-container">
3826+ <details>
3829- <div class="flex1" title="Inserted between the reasoning and the message content." data-i18n="[title]reasoning_separator">
3827+ <summary data-i18n="Reasoning Formatting">
3830- <small data-i18n="Separator">Separator</small>
3828+ Reasoning Formatting
3831- <textarea id="reasoning_separator" class="text_pole textarea_compact autoSetHeight"></textarea>
3829+ </summary>
3830+ <div class="flex-container">
3831+ <div class="flex1" title="Inserted before the reasoning content." data-i18n="[title]reasoning_prefix">
3832+ <small data-i18n="Prefix">Prefix</small>
3833+ <textarea id="reasoning_prefix" class="text_pole textarea_compact autoSetHeight"></textarea>
3834+ </div>
3835+ <div class="flex1" title="Inserted after the reasoning content." data-i18n="[title]reasoning_suffix">
3836+ <small data-i18n="Suffix">Suffix</small>
3837+ <textarea id="reasoning_suffix" class="text_pole textarea_compact autoSetHeight"></textarea>
3838+ </div>
38323839 </div>
3833- <div class="flex1" title="Maximum number of reasoning blocks to be added per prompt, counting from the last message." data-i18n="[title]reasoning_max_additions">
3840+ <div class="flex-container">
3834- <small data-i18n="Max Additions">Max Additions</small>
3841+ <div class="flex1" title="Inserted between the reasoning and the message content." data-i18n="[title]reasoning_separator">
3835- <input id="reasoning_max_additions" class="text_pole textarea_compact" type="number" min="0" max="999"></textarea>
3842+ <small data-i18n="Separator">Separator</small>
3843+ <textarea id="reasoning_separator" class="text_pole textarea_compact autoSetHeight"></textarea>
3844+ </div>
38363845 </div>
38373846 </divdetails>
38383847 </div>
38393848 </div>
38403849 <div>
public/locales/ar-sa.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "فصل بفواصل دون مسافة بينها",
483483 "Custom Stopping Strings": "سلاسل توقف مخصصة",
484484 "JSON serialized array of strings": "مصفوفة سلسلة JSON متسلسلة",
485485 "Replace Macro in Custom StoppingStop Strings": "استبدال الماكرو في سلاسل التوقف المخصصة",
486486 "Auto-Continue": "المتابعة التلقائية",
487487 "Allow for Chat Completion APIs": "السماح بواجهات برمجة التطبيقات لإكمال الدردشة",
488488 "Target length (tokens)": "الطول المستهدف (رموز)",
public/locales/de-de.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "getrennt durch Kommas ohne Leerzeichen dazwischen",
483483 "Custom Stopping Strings": "Benutzerdefinierte Stoppzeichenfolgen",
484484 "JSON serialized array of strings": "JSON serialisierte Reihe von Zeichenfolgen",
485485 "Replace Macro in Custom StoppingStop Strings": "Makro in benutzerdefinierten Stoppzeichenfolgen ersetzen",
486486 "Auto-Continue": "Automatisch fortsetzen",
487487 "Allow for Chat Completion APIs": "Erlaube Chat-Vervollständigungs-APIs",
488488 "Target length (tokens)": "Ziel-Länge (Tokens)",
public/locales/es-es.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "separe con comas sin espacio entre ellas",
483483 "Custom Stopping Strings": "Cadenas de Detención Personalizadas",
484484 "JSON serialized array of strings": "Arreglo de cadenas serializado en JSON",
485485 "Replace Macro in Custom StoppingStop Strings": "Reemplazar macro en Cadenas de Detención Personalizadas",
486486 "Auto-Continue": "Autocontinuar",
487487 "Allow for Chat Completion APIs": "Permitir para APIs de Completado de Chat",
488488 "Target length (tokens)": "Longitud objetivo (tokens)",
public/locales/fr-fr.json+1 -1
@@ -434,7 +434,7 @@
434434 "Non-markdown strings": "Chaînes non Markdown",
435435 "Custom Stopping Strings": "Chaînes d'arrêt personnalisées",
436436 "JSON serialized array of strings": "Tableau de chaînes sérialisé JSON",
437437 "Replace Macro in Custom StoppingStop Strings": "Remplacer les macro dans les chaînes d'arrêt personnalisées",
438438 "Auto-Continue": "Auto-Continue",
439439 "Allow for Chat Completion APIs": "Autoriser les APIs de complétion de chat",
440440 "Target length (tokens)": "Longueur cible (tokens)",
public/locales/is-is.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "aðskilið með kommum án bila milli",
483483 "Custom Stopping Strings": "Eigin stopp-strengir",
484484 "JSON serialized array of strings": "JSON raðað fylki af strengjum",
485485 "Replace Macro in Custom StoppingStop Strings": "Skiptu út í macro í sérsniðnum stoppa strengjum",
486486 "Auto-Continue": "Sjálfvirk Forná",
487487 "Allow for Chat Completion APIs": "Leyfa fyrir spjall Loka APIs",
488488 "Target length (tokens)": "Markaðarlengd (texti)",
public/locales/it-it.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "separati con virgole senza spazio tra loro",
483483 "Custom Stopping Strings": "Stringhe di Stop Personalizzate",
484484 "JSON serialized array of strings": "Matrice serializzata JSON di stringhe",
485485 "Replace Macro in Custom StoppingStop Strings": "Sostituisci Macro in Stringhe di Arresto Personalizzate",
486486 "Auto-Continue": "Auto-continua",
487487 "Allow for Chat Completion APIs": "Consenti per API di completamento chat",
488488 "Target length (tokens)": "Lunghezza obiettivo (token)",
public/locales/ja-jp.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "間にスペースのないカンマで区切ります",
483483 "Custom Stopping Strings": "カスタム停止文字列",
484484 "JSON serialized array of strings": "文字列のJSONシリアル化配列",
485485 "Replace Macro in Custom StoppingStop Strings": "カスタム停止文字列内のマクロを置換する",
486486 "Auto-Continue": "自動継続",
487487 "Allow for Chat Completion APIs": "チャット補完APIを許可",
488488 "Target length (tokens)": "ターゲット長さ(トークン)",
public/locales/ko-kr.json+1 -1
@@ -492,7 +492,7 @@
492492 "separate with commas w/o space between": "쉼표로 구분 (공백 없이)",
493493 "Custom Stopping Strings": "사용자 정의 중지 문자열",
494494 "JSON serialized array of strings": "문자열의 JSON 직렬화된 배열",
495495 "Replace Macro in Custom StoppingStop Strings": "사용자 정의 중단 문자열에서 매크로 교체",
496496 "Auto-Continue": "자동 계속하기",
497497 "Allow for Chat Completion APIs": "채팅 완성 API 허용",
498498 "Target length (tokens)": "대상 길이 (토큰)",
public/locales/nl-nl.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "gescheiden met komma's zonder spatie ertussen",
483483 "Custom Stopping Strings": "Aangepaste Stopreeksen",
484484 "JSON serialized array of strings": "JSON geserialiseerde reeks van strings",
485485 "Replace Macro in Custom StoppingStop Strings": "Macro vervangen in aangepaste stopreeksen",
486486 "Auto-Continue": "Automatisch doorgaan",
487487 "Allow for Chat Completion APIs": "Chatvervolledigings-API's toestaan",
488488 "Target length (tokens)": "Doellengte (tokens)",
public/locales/pt-pt.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "separe com vírgulas sem espaço entre",
483483 "Custom Stopping Strings": "Cadeias de parada personalizadas",
484484 "JSON serialized array of strings": "Matriz de strings serializada em JSON",
485485 "Replace Macro in Custom StoppingStop Strings": "Substituir Macro em Strings de Parada Personalizadas",
486486 "Auto-Continue": "Auto-Continuar",
487487 "Allow for Chat Completion APIs": "Permitir APIs de Completar Chat",
488488 "Target length (tokens)": "Comprimento alvo (tokens)",
public/locales/ru-ru.json+1 -1
@@ -161,7 +161,7 @@
161161 "View hidden API keys": "Посмотреть скрытые API-ключи",
162162 "Advanced Formatting": "Расширенное форматирование",
163163 "Context Template": "Шаблон контекста",
164164 "Replace Macro in Custom StoppingStop Strings": "Заменять макросы в пользовательских стоп-строках",
165165 "Story String": "Строка истории",
166166 "Example Separator": "Разделитель примеров сообщений",
167167 "Chat Start": "Начало чата",
public/locales/uk-ua.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "розділяйте комами без пропусків між ними",
483483 "Custom Stopping Strings": "Власні рядки зупинки",
484484 "JSON serialized array of strings": "JSON-серіалізований масив рядків",
485485 "Replace Macro in Custom StoppingStop Strings": "Замінювати макроси у власних рядках зупинки",
486486 "Auto-Continue": "Автоматичне продовження",
487487 "Allow for Chat Completion APIs": "Дозволити для Chat Completion API",
488488 "Target length (tokens)": "Цільова довжина (токени)",
public/locales/vi-vn.json+1 -1
@@ -482,7 +482,7 @@
482482 "separate with commas w/o space between": "phân tách bằng dấu phẩy không có khoảng trắng giữa",
483483 "Custom Stopping Strings": "Chuỗi dừng tùy chỉnh",
484484 "JSON serialized array of strings": "Mảng chuỗi được tuần tự hóa JSON",
485485 "Replace Macro in Custom StoppingStop Strings": "Thay thế Macro trong Chuỗi Dừng Tùy chỉnh",
486486 "Auto-Continue": "Tự động Tiếp tục",
487487 "Allow for Chat Completion APIs": "Cho phép các API hoàn thành Trò chuyện",
488488 "Target length (tokens)": "Độ dài mục tiêu (token)",
public/locales/zh-cn.json+1 -1
@@ -559,7 +559,7 @@
559559 "Prompt Content": "提示词内容",
560560 "Custom Stopping Strings": "自定义停止字符串",
561561 "JSON serialized array of strings": "JSON序列化的字符串数组",
562562 "Replace Macro in Custom StoppingStop Strings": "替换自定义停止字符串中的宏",
563563 "Token Padding": "词符填充",
564564 "Miscellaneous": "杂项",
565565 "Non-markdown strings": "非 Markdown 字符串",
public/locales/zh-tw.json+1 -1
@@ -483,7 +483,7 @@
483483 "separate with commas w/o space between": "用逗號分隔,之間無空格",
484484 "Custom Stopping Strings": "自訂停止字串",
485485 "JSON serialized array of strings": "JSON 序列化字串數組",
486486 "Replace Macro in Custom StoppingStop Strings": "取代自訂停止字串中的巨集",
487487 "Auto-Continue": "自動繼續",
488488 "Allow for Chat Completion APIs": "允許聊天補全 API",
489489 "Target length (tokens)": "目標長度(符元)",
public/script.js+6 -6
@@ -3451,7 +3451,7 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
34513451 break;
34523452 }
34533453 case 'textgenerationwebui':
34543454 generateData = await getTextGenGenerationData(prompt, amount_gen, false, false, null, 'quiet');
34553455 TempResponseLength.restore(api);
34563456 break;
34573457 case 'openai': {
@@ -4588,7 +4588,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
45884588 break;
45894589 case 'textgenerationwebui': {
45904590 const cfgValues = useCfgPrompt ? { guidanceScale: cfgGuidanceScale, negativePrompt: await getCombinedPrompt(true) } : null;
45914591 generate_data = await getTextGenGenerationData(finalPrompt, maxLength, isImpersonate, isContinue, cfgValues, type);
45924592 break;
45934593 }
45944594 case 'novel': {
@@ -6928,7 +6928,7 @@ export async function getSettings() {
69286928 loadProxyPresets(settings);
69296929
69306930 // Allow subscribers to mutate settings
69316931 await eventSource.emit(event_types.SETTINGS_LOADED_AFTER, settings);
69326932
69336933 // Set context size after loading power user (may override the max value)
69346934 $('#max_context').val(max_context);
@@ -6988,7 +6988,7 @@ export async function getSettings() {
69886988 }
69896989 await validateDisabledSamplers();
69906990 settingsReady = true;
69916991 await eventSource.emit(event_types.SETTINGS_LOADED);
69926992}
69936993
69946994function selectKoboldGuiPreset() {
@@ -11405,7 +11405,7 @@ jQuery(async function () {
1140511405 );
1140611406 break;*/
1140711407 default:
1140811408 await eventSource.emit('charManagementDropdown', target);
1140911409 }
1141011410 $('#char-management-dropdown').prop('selectedIndex', 0);
1141111411 });
@@ -11567,7 +11567,7 @@ jQuery(async function () {
1156711567
1156811568 $(document).on('click', '.open_characters_library', async function () {
1156911569 await getCharacters();
1157011570 await eventSource.emit(event_types.OPEN_CHARACTER_LIBRARY);
1157111571 });
1157211572
1157311573 // Added here to prevent execution before script.js is loaded and get rid of quirky timeouts
public/scripts/chats.js+43 -8
@@ -621,21 +621,56 @@ async function enlargeMessageImage() {
621621}
622622
623623async function deleteMessageImage() {
624624 const value = await callGenericPopup('<h3>Delete image from message?<br>This action can\'t be undone.</h3>', POPUP_TYPE.CONFIRM);TEXT, '', {
625+ okButton: t`Delete one`,
626+ customButtons: [
627+ {
628+ text: t`Delete all`,
629+ appendAtEnd: true,
630+ result: POPUP_RESULT.CUSTOM1,
631+ },
632+ {
633+ text: t`Cancel`,
634+ appendAtEnd: true,
635+ result: POPUP_RESULT.CANCELLED,
636+ },
637+ ],
638+ });
625639
626640 if (value !== POPUP_RESULT.AFFIRMATIVEvalue) {
627641 return;
628642 }
629643
630644 const mesBlock = $(this).closest('.mes');
631645 const mesId = mesBlock.attr('mesid');
632646 const message = chat[mesId];
633- delete message.extra.image;
647+
634- delete message.extra.inline_image;
648+ let isLastImage = true;
635- delete message.extra.title;
649+
636- delete message.extra.append_title;
650+ if (Array.isArray(message.extra.image_swipes)) {
637- mesBlock.find('.mes_img_container').removeClass('img_extra');
651+ const indexOf = message.extra.image_swipes.indexOf(message.extra.image);
638- mesBlock.find('.mes_img').attr('src', '');
652+ if (indexOf > -1) {
653+ message.extra.image_swipes.splice(indexOf, 1);
654+ isLastImage = message.extra.image_swipes.length === 0;
655+ if (!isLastImage) {
656+ const newIndex = Math.min(indexOf, message.extra.image_swipes.length - 1);
657+ message.extra.image = message.extra.image_swipes[newIndex];
658+ }
659+ }
660+ }
661+
662+ if (isLastImage || value === POPUP_RESULT.CUSTOM1) {
663+ delete message.extra.image;
664+ delete message.extra.inline_image;
665+ delete message.extra.title;
666+ delete message.extra.append_title;
667+ delete message.extra.image_swipes;
668+ mesBlock.find('.mes_img_container').removeClass('img_extra');
669+ mesBlock.find('.mes_img').attr('src', '');
670+ } else {
671+ appendMediaToMessage(message, mesBlock);
672+ }
673+
639674 await saveChatConditional();
640675}
641676
public/scripts/extensions/caption/settings.html+1 -1
@@ -10,7 +10,7 @@
1010 <select id="caption_source" class="text_pole">
1111 <option value="local" data-i18n="Local">Local</option>
1212 <option value="multimodal" data-i18n="Multimodal (OpenAI / Anthropic / llama / Google)">Multimodal (OpenAI / Anthropic / llama / Google)</option>
1313 <option value="extras" data-i18n="Extras">Extras (deprecated)</option>
1414 <option value="horde" data-i18n="Horde">Horde</option>
1515 </select>
1616 <div id="caption_multimodal_block" class="flex-container wide100p">
public/scripts/extensions/expressions/settings.html+1 -1
@@ -23,7 +23,7 @@
2323 <small data-i18n="Select the API for classifying expressions.">Select the API for classifying expressions.</small>
2424 <select id="expression_api" class="flex1 margin0">
2525 <option value="0" data-i18n="Local">Local</option>
2626 <option value="1" data-i18n="Extras">Extras (deprecated)</option>
2727 <option value="2" data-i18n="Main API">Main API</option>
2828 <option value="3" data-i18n="WebLLM Extension">WebLLM Extension</option>
2929 </select>
public/scripts/extensions/memory/settings.html+1 -1
@@ -12,7 +12,7 @@
1212 <label for="summary_source" data-i18n="ext_sum_with">Summarize with:</label>
1313 <select id="summary_source">
1414 <option value="main" data-i18n="ext_sum_main_api">Main API</option>
1515 <option value="extras">Extras API (deprecated)</option>
1616 <option value="webllm" data-i18n="ext_sum_webllm">WebLLM Extension</option>
1717 </select><br>
1818
public/scripts/extensions/stable-diffusion/settings.html+1 -1
@@ -41,7 +41,7 @@
4141 <option value="blockentropy">Block Entropy</option>
4242 <option value="comfy">ComfyUI</option>
4343 <option value="drawthings">DrawThings HTTP API</option>
4444 <option value="extras">Extras API (local / remotedeprecated)</option>
4545 <option value="huggingface">HuggingFace Inference API (serverless)</option>
4646 <option value="nanogpt">NanoGPT</option>
4747 <option value="novel">NovelAI Diffusion</option>
public/scripts/extensions/vectors/settings.html+1 -1
@@ -11,7 +11,7 @@
1111 </label>
1212 <select id="vectors_source" class="text_pole">
1313 <option value="cohere">Cohere</option>
1414 <option value="extras">Extras (deprecated)</option>
1515 <option value="palm">Google AI Studio</option>
1616 <option value="llamacpp">llama.cpp</option>
1717 <option value="transformers" data-i18n="Local (Transformers)">Local (Transformers)</option>
public/scripts/popup.js+9 -0
@@ -24,6 +24,15 @@ export const POPUP_RESULT = {
2424 AFFIRMATIVE: 1,
2525 NEGATIVE: 0,
2626 CANCELLED: null,
27+ CUSTOM1: 1001,
28+ CUSTOM2: 1002,
29+ CUSTOM3: 1003,
30+ CUSTOM4: 1004,
31+ CUSTOM5: 1005,
32+ CUSTOM6: 1006,
33+ CUSTOM7: 1007,
34+ CUSTOM8: 1008,
35+ CUSTOM9: 1009,
2736};
2837
2938/**
public/scripts/power-user.js+1 -1
@@ -2451,7 +2451,7 @@ async function resetMovablePanels(type) {
24512451 }
24522452
24532453 saveSettingsDebounced();
24542454 await eventSource.emit(event_types.MOVABLE_PANELS_RESET);
24552455
24562456 eventSource.once(event_types.SETTINGS_UPDATED, () => {
24572457 $('.resizing').removeClass('resizing');
public/scripts/secrets.js+1 -0
@@ -40,6 +40,7 @@ export const SECRET_KEYS = {
4040 BFL: 'api_key_bfl',
4141 GENERIC: 'api_key_generic',
4242 DEEPSEEK: 'api_key_deepseek',
43+ SERPER: 'api_key_serper',
4344};
4445
4546const INPUT_MAP = {
public/scripts/textgen-settings.js+2 -2
@@ -1221,7 +1221,7 @@ function replaceMacrosInList(str) {
12211221 }
12221222}
12231223
12241224export async function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate, isContinue, cfgValues, type) {
12251225 const canMultiSwipe = !isContinue && !isImpersonate && type !== 'quiet';
12261226 const dynatemp = isDynamicTemperatureSupported();
12271227 const { banned_tokens, banned_strings } = getCustomTokenBans();
@@ -1449,7 +1449,7 @@ export function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate,
14491449 }
14501450 }
14511451
14521452 await eventSource.emitAndWaitemit(event_types.TEXT_COMPLETION_SETTINGS_READY, params);
14531453
14541454 // Grammar conflicts with with json_schema
14551455 if (settings.type === LLAMACPP) {
public/scripts/world-info.js+1 -1
@@ -3452,7 +3452,7 @@ async function _save(name, data) {
34523452 headers: getRequestHeaders(),
34533453 body: JSON.stringify({ name: name, data: data }),
34543454 });
34553455 await eventSource.emit(event_types.WORLDINFO_UPDATED, name, data);
34563456}
34573457
34583458
public/style.css+2 -0
@@ -5745,11 +5745,13 @@ body:not(.movingUI) .drawer-content.maximized {
57455745 overflow-wrap: anywhere;
57465746}
57475747
5748+#SystemPromptColumn summary,
57485749#InstructSequencesColumn summary {
57495750 font-size: 0.95em;
57505751 cursor: pointer;
57515752}
57525753
5754+#SystemPromptColumn details,
57535755#InstructSequencesColumn details:not(:last-of-type) {
57545756 margin-bottom: 5px;
57555757}
src/endpoints/search.js+45 -0
@@ -112,6 +112,7 @@ router.post('/serpapi', jsonParser, async (request, response) => {
112112 }
113113
114114 const data = await result.json();
115+ console.debug('SerpApi response', data);
115116 return response.json(data);
116117 } catch (error) {
117118 console.error(error);
@@ -255,6 +256,7 @@ router.post('/tavily', jsonParser, async (request, response) => {
255256 }
256257
257258 const data = await result.json();
259+ console.debug('Tavily response', data);
258260 return response.json(data);
259261 } catch (error) {
260262 console.error(error);
@@ -290,6 +292,49 @@ router.post('/koboldcpp', jsonParser, async (request, response) => {
290292 }
291293
292294 const data = await result.json();
295+ console.debug('KoboldCpp search response', data);
296+ return response.json(data);
297+ } catch (error) {
298+ console.error(error);
299+ return response.sendStatus(500);
300+ }
301+});
302+
303+router.post('/serper', jsonParser, async (request, response) => {
304+ try {
305+ const key = readSecret(request.user.directories, SECRET_KEYS.SERPER);
306+
307+ if (!key) {
308+ console.error('No Serper key found');
309+ return response.sendStatus(400);
310+ }
311+
312+ const { query, images } = request.body;
313+
314+ const url = images
315+ ? 'https://google.serper.dev/images'
316+ : 'https://google.serper.dev/search';
317+
318+ const result = await fetch(url, {
319+ method: 'POST',
320+ headers: {
321+ 'X-API-KEY': key,
322+ 'Content-Type': 'application/json',
323+ },
324+ redirect: 'follow',
325+ body: JSON.stringify({ q: query }),
326+ });
327+
328+ console.debug('Serper query', query);
329+
330+ if (!result.ok) {
331+ const text = await result.text();
332+ console.warn('Serper request failed', result.statusText, text);
333+ return response.status(500).send(text);
334+ }
335+
336+ const data = await result.json();
337+ console.debug('Serper response', data);
293338 return response.json(data);
294339 } catch (error) {
295340 console.error(error);
src/endpoints/secrets.js+1 -0
@@ -52,6 +52,7 @@ export const SECRET_KEYS = {
5252 BFL: 'api_key_bfl',
5353 GENERIC: 'api_key_generic',
5454 DEEPSEEK: 'api_key_deepseek',
55+ SERPER: 'api_key_serper',
5556};
5657
5758// These are the keys that are safe to expose, even if allowKeysExposure is false