Add 'none' classifier API option and set as default Introduces a no-op API selection to disable expression classification Shows warnings when no valid API is selected to prevent silent failures Updates migration logic and settings UI to use new default value This allows users to explicitly opt-out of automatic expression detection while maintaining backwards compatibility with existing configurations

cbfc1f7a0e801c4931ea97e3c1c78b46cb86e2bf

Wolfsblvt <wolfsblvt@gmail.com>

2 files changed, +19 -3Showing whitespace changes
public/scripts/extensions/expressions/index.js+18 -3
@@ -83,6 +83,7 @@ const EXPRESSION_API = {
8383 extras: 1,
8484 llm: 2,
8585 webllm: 3,
86+ none: 99,
8687};
8788
8889let expressionsList = null;
@@ -692,6 +693,11 @@ async function classifyCallback(/** @type {{api: string?, filter: string?, promp
692693 const expressionApi = EXPRESSION_API[api] || extension_settings.expressions.api;
693694 const filterAvailable = !isFalseBoolean(filter);
694695
696+ if (expressionApi === EXPRESSION_API.none) {
697+ toastr.warning('No classifier API selected');
698+ return '';
699+ }
700+
695701 if (!modules.includes('classify') && expressionApi == EXPRESSION_API.extras) {
696702 toastr.warning('Text classification is disabled or not available');
697703 return '';
@@ -1061,7 +1067,7 @@ export async function getExpressionLabel(text, expressionsApi = extension_settin
10611067 return parseLlmResponse(emotionResponse, expressionsList);
10621068 }
10631069 // Extras
10641070 defaultcase EXPRESSION_API.extras: {
10651071 const url = new URL(getApiUrl());
10661072 url.pathname = '/api/classify';
10671073
@@ -1079,6 +1085,15 @@ export async function getExpressionLabel(text, expressionsApi = extension_settin
10791085 return data.classification[0].label;
10801086 }
10811087 } break;
1088+ // None
1089+ case EXPRESSION_API.none: {
1090+ // Return empty, the fallback expression will be used
1091+ return '';
1092+ }
1093+ default: {
1094+ toastr.error('Invalid API selected');
1095+ return '';
1096+ }
10821097 }
10831098 } catch (error) {
10841099 toastr.error('Could not classify expression. Check the console or your backend for more information.');
@@ -2060,7 +2075,7 @@ async function fetchImagesNoCache() {
20602075
20612076function migrateSettings() {
20622077 if (extension_settings.expressions.api === undefined) {
20632078 extension_settings.expressions.api = EXPRESSION_API.localnone;
20642079 saveSettingsDebounced();
20652080 }
20662081
@@ -2142,7 +2157,7 @@ function migrateSettings() {
21422157 $('#open_chat_expressions').hide();
21432158
21442159 await renderAdditionalExpressionSettings();
21452160 $('#expression_api').val(extension_settings.expressions.api ?? EXPRESSION_API.extrasnone);
21462161 $('.expression_llm_prompt_block').toggle([EXPRESSION_API.llm, EXPRESSION_API.webllm].includes(extension_settings.expressions.api));
21472162 $('#expression_llm_prompt').val(extension_settings.expressions.llmPrompt ?? '');
21482163 $('#expression_llm_prompt').on('input', function () {
public/scripts/extensions/expressions/settings.html+1 -0
@@ -22,6 +22,7 @@
2222 <label for="expression_api" data-i18n="Classifier API">Classifier API</label>
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">
25+ <option value="99" data-i18n="[ None ]">[ None ]</option>
2526 <option value="0" data-i18n="Local">Local</option>
2627 <option value="1" data-i18n="Extras">Extras (deprecated)</option>
2728 <option value="2" data-i18n="Main API">Main API</option>