mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Merge pull request #3213 from SillyTavern/expressions-webllm
Expressions: Add WebLLM extension classification
This commit is contained in:
		| @@ -15,6 +15,7 @@ import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashComm | |||||||
| import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | ||||||
| import { slashCommandReturnHelper } from '../../slash-commands/SlashCommandReturnHelper.js'; | import { slashCommandReturnHelper } from '../../slash-commands/SlashCommandReturnHelper.js'; | ||||||
| import { SlashCommandClosure } from '../../slash-commands/SlashCommandClosure.js'; | import { SlashCommandClosure } from '../../slash-commands/SlashCommandClosure.js'; | ||||||
|  | import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js'; | ||||||
| export { MODULE_NAME }; | export { MODULE_NAME }; | ||||||
|  |  | ||||||
| const MODULE_NAME = 'expressions'; | const MODULE_NAME = 'expressions'; | ||||||
| @@ -59,6 +60,7 @@ const EXPRESSION_API = { | |||||||
|     local: 0, |     local: 0, | ||||||
|     extras: 1, |     extras: 1, | ||||||
|     llm: 2, |     llm: 2, | ||||||
|  |     webllm: 3, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| let expressionsList = null; | let expressionsList = null; | ||||||
| @@ -852,7 +854,7 @@ function setTalkingHeadState(newState) { | |||||||
|     extension_settings.expressions.talkinghead = newState; // Store setting |     extension_settings.expressions.talkinghead = newState; // Store setting | ||||||
|     saveSettingsDebounced(); |     saveSettingsDebounced(); | ||||||
|  |  | ||||||
|     if (extension_settings.expressions.api == EXPRESSION_API.local || extension_settings.expressions.api == EXPRESSION_API.llm) { |     if ([EXPRESSION_API.local, EXPRESSION_API.llm, EXPRESSION_API.webllm].includes(extension_settings.expressions.api)) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1057,21 +1059,25 @@ function parseLlmResponse(emotionResponse, labels) { | |||||||
|             console.debug(`fuzzy search found: ${result[0].item} as closest for the LLM response:`, emotionResponse); |             console.debug(`fuzzy search found: ${result[0].item} as closest for the LLM response:`, emotionResponse); | ||||||
|             return result[0].item; |             return result[0].item; | ||||||
|         } |         } | ||||||
|  |         const lowerCaseResponse = String(emotionResponse || '').toLowerCase(); | ||||||
|  |         for (const label of labels) { | ||||||
|  |             if (lowerCaseResponse.includes(label.toLowerCase())) { | ||||||
|  |                 console.debug(`Found label ${label} in the LLM response:`, emotionResponse); | ||||||
|  |                 return label; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     throw new Error('Could not parse emotion response ' + emotionResponse); |     throw new Error('Could not parse emotion response ' + emotionResponse); | ||||||
| } | } | ||||||
|  |  | ||||||
| function onTextGenSettingsReady(args) { | /** | ||||||
|     // Only call if inside an API call |  * Gets the JSON schema for the LLM API. | ||||||
|     if (inApiCall && extension_settings.expressions.api === EXPRESSION_API.llm && isJsonSchemaSupported()) { |  * @param {string[]} emotions A list of emotions to search for. | ||||||
|         const emotions = DEFAULT_EXPRESSIONS.filter((e) => e != 'talkinghead'); |  * @returns {object} The JSON schema for the LLM API. | ||||||
|         Object.assign(args, { |  */ | ||||||
|             top_k: 1, | function getJsonSchema(emotions) { | ||||||
|             stop: [], |     return { | ||||||
|             stopping_strings: [], |  | ||||||
|             custom_token_bans: [], |  | ||||||
|             json_schema: { |  | ||||||
|         $schema: 'http://json-schema.org/draft-04/schema#', |         $schema: 'http://json-schema.org/draft-04/schema#', | ||||||
|         type: 'object', |         type: 'object', | ||||||
|         properties: { |         properties: { | ||||||
| @@ -1083,7 +1089,19 @@ function onTextGenSettingsReady(args) { | |||||||
|         required: [ |         required: [ | ||||||
|             'emotion', |             'emotion', | ||||||
|         ], |         ], | ||||||
|             }, |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function onTextGenSettingsReady(args) { | ||||||
|  |     // Only call if inside an API call | ||||||
|  |     if (inApiCall && extension_settings.expressions.api === EXPRESSION_API.llm && isJsonSchemaSupported()) { | ||||||
|  |         const emotions = DEFAULT_EXPRESSIONS.filter((e) => e != 'talkinghead'); | ||||||
|  |         Object.assign(args, { | ||||||
|  |             top_k: 1, | ||||||
|  |             stop: [], | ||||||
|  |             stopping_strings: [], | ||||||
|  |             custom_token_bans: [], | ||||||
|  |             json_schema: getJsonSchema(emotions), | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -1139,6 +1157,22 @@ export async function getExpressionLabel(text, expressionsApi = extension_settin | |||||||
|                 const emotionResponse = await generateRaw(text, main_api, false, false, prompt); |                 const emotionResponse = await generateRaw(text, main_api, false, false, prompt); | ||||||
|                 return parseLlmResponse(emotionResponse, expressionsList); |                 return parseLlmResponse(emotionResponse, expressionsList); | ||||||
|             } |             } | ||||||
|  |             // Using WebLLM | ||||||
|  |             case EXPRESSION_API.webllm: { | ||||||
|  |                 if (!isWebLlmSupported()) { | ||||||
|  |                     console.warn('WebLLM is not supported. Using fallback expression'); | ||||||
|  |                     return getFallbackExpression(); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 const expressionsList = await getExpressionsList(); | ||||||
|  |                 const prompt = substituteParamsExtended(customPrompt, { labels: expressionsList }) || await getLlmPrompt(expressionsList); | ||||||
|  |                 const messages = [ | ||||||
|  |                     { role: 'user', content: text + '\n\n' + prompt }, | ||||||
|  |                 ]; | ||||||
|  |  | ||||||
|  |                 const emotionResponse = await generateWebLlmChatPrompt(messages); | ||||||
|  |                 return parseLlmResponse(emotionResponse, expressionsList); | ||||||
|  |             } | ||||||
|             // Extras |             // Extras | ||||||
|             default: { |             default: { | ||||||
|                 const url = new URL(getApiUrl()); |                 const url = new URL(getApiUrl()); | ||||||
| @@ -1603,7 +1637,7 @@ function onExpressionApiChanged() { | |||||||
|     const tempApi = this.value; |     const tempApi = this.value; | ||||||
|     if (tempApi) { |     if (tempApi) { | ||||||
|         extension_settings.expressions.api = Number(tempApi); |         extension_settings.expressions.api = Number(tempApi); | ||||||
|         $('.expression_llm_prompt_block').toggle(extension_settings.expressions.api === EXPRESSION_API.llm); |         $('.expression_llm_prompt_block').toggle([EXPRESSION_API.llm, EXPRESSION_API.webllm].includes(extension_settings.expressions.api)); | ||||||
|         expressionsList = null; |         expressionsList = null; | ||||||
|         spriteCache = {}; |         spriteCache = {}; | ||||||
|         moduleWorker(); |         moduleWorker(); | ||||||
| @@ -1940,7 +1974,7 @@ function migrateSettings() { | |||||||
|  |  | ||||||
|         await renderAdditionalExpressionSettings(); |         await renderAdditionalExpressionSettings(); | ||||||
|         $('#expression_api').val(extension_settings.expressions.api ?? EXPRESSION_API.extras); |         $('#expression_api').val(extension_settings.expressions.api ?? EXPRESSION_API.extras); | ||||||
|         $('.expression_llm_prompt_block').toggle(extension_settings.expressions.api === EXPRESSION_API.llm); |         $('.expression_llm_prompt_block').toggle([EXPRESSION_API.llm, EXPRESSION_API.webllm].includes(extension_settings.expressions.api)); | ||||||
|         $('#expression_llm_prompt').val(extension_settings.expressions.llmPrompt ?? ''); |         $('#expression_llm_prompt').val(extension_settings.expressions.llmPrompt ?? ''); | ||||||
|         $('#expression_llm_prompt').on('input', function () { |         $('#expression_llm_prompt').on('input', function () { | ||||||
|             extension_settings.expressions.llmPrompt = $(this).val(); |             extension_settings.expressions.llmPrompt = $(this).val(); | ||||||
|   | |||||||
| @@ -24,7 +24,8 @@ | |||||||
|                 <select id="expression_api" class="flex1 margin0"> |                 <select id="expression_api" class="flex1 margin0"> | ||||||
|                     <option value="0" data-i18n="Local">Local</option> |                     <option value="0" data-i18n="Local">Local</option> | ||||||
|                     <option value="1" data-i18n="Extras">Extras</option> |                     <option value="1" data-i18n="Extras">Extras</option> | ||||||
|                     <option value="2" data-i18n="LLM">LLM</option> |                     <option value="2" data-i18n="Main API">Main API</option> | ||||||
|  |                     <option value="3" data-i18n="WebLLM Extension">WebLLM Extension</option> | ||||||
|                 </select> |                 </select> | ||||||
|             </div> |             </div> | ||||||
|             <div class="expression_llm_prompt_block m-b-1 m-t-1"> |             <div class="expression_llm_prompt_block m-b-1 m-t-1"> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user