Merge branch 'staging' into neo-server
This commit is contained in:
commit
0263be8c1f
|
@ -68,6 +68,8 @@ module.exports = {
|
|||
'no-trailing-spaces': 'error',
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
'space-infix-ops': 'error',
|
||||
'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
|
||||
'no-cond-assign': 'error',
|
||||
|
||||
// These rules should eventually be enabled.
|
||||
'no-async-promise-executor': 'off',
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
padding: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 999999;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
@ -20,6 +17,15 @@
|
|||
}
|
||||
|
||||
#load-spinner {
|
||||
--spinner-size: 2em;
|
||||
transition: all 300ms ease-out;
|
||||
opacity: 1;
|
||||
top: calc(50% - var(--spinner-size) / 2);
|
||||
left: calc(50% - var(--spinner-size) / 2);
|
||||
position: absolute;
|
||||
width: var(--spinner-size);
|
||||
height: var(--spinner-size);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
|
@ -459,6 +459,17 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="cohere">
|
||||
<label for="websearch_toggle" title="Enable Cohere web-search connector" data-i18n="[title]Enable Cohere web-search connector" class="checkbox_label widthFreeExpand">
|
||||
<input id="websearch_toggle" type="checkbox" />
|
||||
<span data-i18n="Web-search">Web-search</span>
|
||||
</label>
|
||||
<div class="toggle-description justifyLeft">
|
||||
<span data-i18n="Allow the model to use the web-search connector.">
|
||||
Allow the model to use the web-search connector.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="range-block" data-source="openai,claude,windowai,openrouter,ai21,scale,makersuite,mistralai,custom,cohere">
|
||||
<div class="range-block-title" data-i18n="Temperature">
|
||||
Temperature
|
||||
|
@ -3848,7 +3859,7 @@
|
|||
<input id="prefer_character_jailbreak" type="checkbox" />
|
||||
<span data-i18n="Prefer Character Card Jailbreak">Prefer Char. Jailbreak</span>
|
||||
</label>
|
||||
<label data-newbie-hidden class="checkbox_label" for="never_resize_avatars" title="Avoid cropping and resizing imported character images. When off, crop/resize to 400x600." data-i18n="[title]Avoid cropping and resizing imported character images. When off, crop/resize to 400x600">
|
||||
<label data-newbie-hidden class="checkbox_label" for="never_resize_avatars" title="Avoid cropping and resizing imported character images. When off, crop/resize to 512x768." data-i18n="[title]Avoid cropping and resizing imported character images. When off, crop/resize to 512x768">
|
||||
<input id="never_resize_avatars" type="checkbox" />
|
||||
<span data-i18n="Never resize avatars">Never resize avatars</span>
|
||||
</label>
|
||||
|
|
|
@ -858,11 +858,11 @@ async function firstLoadInit() {
|
|||
throw new Error('Initialization failed');
|
||||
}
|
||||
|
||||
await readSecretState();
|
||||
await getSettings();
|
||||
await getSystemMessages();
|
||||
sendSystemMessage(system_message_types.WELCOME);
|
||||
await getClientVersion();
|
||||
await readSecretState();
|
||||
await getSettings();
|
||||
initLocales();
|
||||
initTags();
|
||||
await getUserAvatars(true, user_avatar);
|
||||
|
@ -2444,9 +2444,14 @@ function sendSystemMessage(type, text, extra = {}) {
|
|||
is_send_press = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the contents of bias macros from a message.
|
||||
* @param {string} message Message text
|
||||
* @returns {string} Message bias extracted from the message (or an empty string if not found)
|
||||
*/
|
||||
export function extractMessageBias(message) {
|
||||
if (!message) {
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -3067,14 +3072,14 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
|
||||
if (interruptedByCommand) {
|
||||
//$("#send_textarea").val('').trigger('input');
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
if (main_api == 'kobold' && kai_settings.streaming_kobold && !kai_flags.can_use_streaming) {
|
||||
toastr.error('Streaming is enabled, but the version of Kobold used does not support token streaming.', undefined, { timeOut: 10000, preventDuplicates: true });
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
@ -3083,12 +3088,12 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
textgen_settings.legacy_api &&
|
||||
(textgen_settings.type === OOBA || textgen_settings.type === APHRODITE)) {
|
||||
toastr.error('Streaming is not supported for the Legacy API. Update Ooba and use new API to enable streaming.', undefined, { timeOut: 10000, preventDuplicates: true });
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (isHordeGenerationNotAllowed()) {
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
@ -3124,7 +3129,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
setCharacterName('');
|
||||
} else {
|
||||
console.log('No enabled members found');
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
@ -3298,7 +3303,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
|
||||
if (aborted) {
|
||||
console.debug('Generation aborted by extension interceptors');
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
} else {
|
||||
|
@ -3312,7 +3317,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
adjustedParams = await adjustHordeGenerationParams(max_context, amount_gen);
|
||||
}
|
||||
catch {
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (horde_settings.auto_adjust_context_length) {
|
||||
|
@ -4099,7 +4104,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
await eventSource.emit(event_types.IMPERSONATE_READY, getMessage);
|
||||
}
|
||||
else if (type == 'quiet') {
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
return getMessage;
|
||||
}
|
||||
else {
|
||||
|
@ -4167,7 +4172,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
|
||||
console.debug('/api/chats/save called by /Generate');
|
||||
await saveChatConditional();
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
streamingProcessor = null;
|
||||
|
||||
if (type !== 'quiet') {
|
||||
|
@ -4185,7 +4190,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
|
|||
|
||||
generatedPromptCache = '';
|
||||
|
||||
unblockGeneration();
|
||||
unblockGeneration(type);
|
||||
console.log(exception);
|
||||
streamingProcessor = null;
|
||||
throw exception;
|
||||
|
@ -4255,7 +4260,16 @@ function flushWIDepthInjections() {
|
|||
}
|
||||
}
|
||||
|
||||
function unblockGeneration() {
|
||||
/**
|
||||
* Unblocks the UI after a generation is complete.
|
||||
* @param {string} [type] Generation type (optional)
|
||||
*/
|
||||
function unblockGeneration(type) {
|
||||
// Don't unblock if a parallel stream is still running
|
||||
if (type === 'quiet' && streamingProcessor && !streamingProcessor.isFinished) {
|
||||
return;
|
||||
}
|
||||
|
||||
is_send_press = false;
|
||||
activateSendButtons();
|
||||
showSwipeButtons();
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDebounced } from '../../../script.js';
|
||||
import { callPopup, eventSource, event_types, generateQuietPrompt, getRequestHeaders, saveSettingsDebounced, substituteParams } from '../../../script.js';
|
||||
import { dragElement, isMobile } from '../../RossAscends-mods.js';
|
||||
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js';
|
||||
import { loadMovingUIState, power_user } from '../../power-user.js';
|
||||
import { registerSlashCommand } from '../../slash-commands.js';
|
||||
import { onlyUnique, debounce, getCharaFilename, trimToEndSentence, trimToStartSentence } from '../../utils.js';
|
||||
import { hideMutedSprites } from '../../group-chats.js';
|
||||
import { isJsonSchemaSupported } from '../../textgen-settings.js';
|
||||
export { MODULE_NAME };
|
||||
|
||||
const MODULE_NAME = 'expressions';
|
||||
const UPDATE_INTERVAL = 2000;
|
||||
const STREAMING_UPDATE_INTERVAL = 6000;
|
||||
const STREAMING_UPDATE_INTERVAL = 10000;
|
||||
const TALKINGCHECK_UPDATE_INTERVAL = 500;
|
||||
const DEFAULT_FALLBACK_EXPRESSION = 'joy';
|
||||
const DEFAULT_LLM_PROMPT = 'Pause your roleplay. Classify the emotion of the last message. Output just one word, e.g. "joy" or "anger". Choose only one of the following labels: {{labels}}';
|
||||
const DEFAULT_EXPRESSIONS = [
|
||||
'talkinghead',
|
||||
'admiration',
|
||||
|
@ -43,6 +45,11 @@ const DEFAULT_EXPRESSIONS = [
|
|||
'surprise',
|
||||
'neutral',
|
||||
];
|
||||
const EXPRESSION_API = {
|
||||
local: 0,
|
||||
extras: 1,
|
||||
llm: 2,
|
||||
};
|
||||
|
||||
let expressionsList = null;
|
||||
let lastCharacter = undefined;
|
||||
|
@ -55,7 +62,7 @@ let lastServerResponseTime = 0;
|
|||
export let lastExpression = {};
|
||||
|
||||
function isTalkingHeadEnabled() {
|
||||
return extension_settings.expressions.talkinghead && !extension_settings.expressions.local;
|
||||
return extension_settings.expressions.talkinghead && extension_settings.expressions.api == EXPRESSION_API.extras;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -585,10 +592,10 @@ function handleImageChange() {
|
|||
async function moduleWorker() {
|
||||
const context = getContext();
|
||||
|
||||
// Hide and disable Talkinghead while in local mode
|
||||
$('#image_type_block').toggle(!extension_settings.expressions.local);
|
||||
// Hide and disable Talkinghead while not in extras
|
||||
$('#image_type_block').toggle(extension_settings.expressions.api == EXPRESSION_API.extras);
|
||||
|
||||
if (extension_settings.expressions.local && extension_settings.expressions.talkinghead) {
|
||||
if (extension_settings.expressions.api != EXPRESSION_API.extras && extension_settings.expressions.talkinghead) {
|
||||
$('#image_type_toggle').prop('checked', false);
|
||||
setTalkingHeadState(false);
|
||||
}
|
||||
|
@ -628,7 +635,7 @@ async function moduleWorker() {
|
|||
}
|
||||
|
||||
const offlineMode = $('.expression_settings .offline_mode');
|
||||
if (!modules.includes('classify') && !extension_settings.expressions.local) {
|
||||
if (!modules.includes('classify') && extension_settings.expressions.api == EXPRESSION_API.extras) {
|
||||
$('#open_chat_expressions').show();
|
||||
$('#no_chat_expressions').hide();
|
||||
offlineMode.css('display', 'block');
|
||||
|
@ -821,7 +828,7 @@ function setTalkingHeadState(newState) {
|
|||
extension_settings.expressions.talkinghead = newState; // Store setting
|
||||
saveSettingsDebounced();
|
||||
|
||||
if (extension_settings.expressions.local) {
|
||||
if (extension_settings.expressions.api == EXPRESSION_API.local || extension_settings.expressions.api == EXPRESSION_API.llm) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -900,7 +907,7 @@ async function classifyCommand(_, text) {
|
|||
return '';
|
||||
}
|
||||
|
||||
if (!modules.includes('classify') && !extension_settings.expressions.local) {
|
||||
if (!modules.includes('classify') && extension_settings.expressions.api == EXPRESSION_API.extras) {
|
||||
toastr.warning('Text classification is disabled or not available');
|
||||
return '';
|
||||
}
|
||||
|
@ -971,9 +978,76 @@ function sampleClassifyText(text) {
|
|||
return result.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the classification prompt for the LLM API.
|
||||
* @param {string[]} labels A list of labels to search for.
|
||||
* @returns {Promise<string>} Prompt for the LLM API.
|
||||
*/
|
||||
async function getLlmPrompt(labels) {
|
||||
if (isJsonSchemaSupported()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const labelsString = labels.map(x => `"${x}"`).join(', ');
|
||||
const prompt = substituteParams(String(extension_settings.expressions.llmPrompt))
|
||||
.replace(/{{labels}}/gi, labelsString);
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the emotion response from the LLM API.
|
||||
* @param {string} emotionResponse The response from the LLM API.
|
||||
* @param {string[]} labels A list of labels to search for.
|
||||
* @returns {string} The parsed emotion or the fallback expression.
|
||||
*/
|
||||
function parseLlmResponse(emotionResponse, labels) {
|
||||
const fallbackExpression = getFallbackExpression();
|
||||
|
||||
try {
|
||||
const parsedEmotion = JSON.parse(emotionResponse);
|
||||
return parsedEmotion?.emotion ?? fallbackExpression;
|
||||
} catch {
|
||||
const fuse = new Fuse([emotionResponse]);
|
||||
for (const label of labels) {
|
||||
const result = fuse.search(label);
|
||||
if (result.length > 0) {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Could not parse emotion response ' + emotionResponse);
|
||||
}
|
||||
|
||||
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: {
|
||||
$schema: 'http://json-schema.org/draft-04/schema#',
|
||||
type: 'object',
|
||||
properties: {
|
||||
emotion: {
|
||||
type: 'string',
|
||||
enum: emotions,
|
||||
},
|
||||
},
|
||||
required: [
|
||||
'emotion',
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function getExpressionLabel(text) {
|
||||
// Return if text is undefined, saving a costly fetch request
|
||||
if ((!modules.includes('classify') && !extension_settings.expressions.local) || !text) {
|
||||
if ((!modules.includes('classify') && extension_settings.expressions.api == EXPRESSION_API.extras) || !text) {
|
||||
return getFallbackExpression();
|
||||
}
|
||||
|
||||
|
@ -984,39 +1058,50 @@ async function getExpressionLabel(text) {
|
|||
text = sampleClassifyText(text);
|
||||
|
||||
try {
|
||||
if (extension_settings.expressions.local) {
|
||||
// Local transformers pipeline
|
||||
const apiResult = await fetch('/api/extra/classify', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({ text: text }),
|
||||
});
|
||||
switch (extension_settings.expressions.api) {
|
||||
// Local BERT pipeline
|
||||
case EXPRESSION_API.local: {
|
||||
const localResult = await fetch('/api/extra/classify', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
body: JSON.stringify({ text: text }),
|
||||
});
|
||||
|
||||
if (apiResult.ok) {
|
||||
const data = await apiResult.json();
|
||||
return data.classification[0].label;
|
||||
if (localResult.ok) {
|
||||
const data = await localResult.json();
|
||||
return data.classification[0].label;
|
||||
}
|
||||
} break;
|
||||
// Using LLM
|
||||
case EXPRESSION_API.llm: {
|
||||
const expressionsList = await getExpressionsList();
|
||||
const prompt = await getLlmPrompt(expressionsList);
|
||||
const emotionResponse = await generateQuietPrompt(prompt, false, false);
|
||||
return parseLlmResponse(emotionResponse, expressionsList);
|
||||
}
|
||||
} else {
|
||||
// Extras
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/classify';
|
||||
default: {
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/classify';
|
||||
|
||||
const apiResult = await doExtrasFetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Bypass-Tunnel-Reminder': 'bypass',
|
||||
},
|
||||
body: JSON.stringify({ text: text }),
|
||||
});
|
||||
const extrasResult = await doExtrasFetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Bypass-Tunnel-Reminder': 'bypass',
|
||||
},
|
||||
body: JSON.stringify({ text: text }),
|
||||
});
|
||||
|
||||
if (apiResult.ok) {
|
||||
const data = await apiResult.json();
|
||||
return data.classification[0].label;
|
||||
}
|
||||
if (extrasResult.ok) {
|
||||
const data = await extrasResult.json();
|
||||
return data.classification[0].label;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toastr.info('Could not classify expression. Check the console or your backend for more information.');
|
||||
console.error(error);
|
||||
return getFallbackExpression();
|
||||
}
|
||||
}
|
||||
|
@ -1177,23 +1262,12 @@ async function getExpressionsList() {
|
|||
*/
|
||||
async function resolveExpressionsList() {
|
||||
// get something for offline mode (default images)
|
||||
if (!modules.includes('classify') && !extension_settings.expressions.local) {
|
||||
if (!modules.includes('classify') && extension_settings.expressions.api == EXPRESSION_API.extras) {
|
||||
return DEFAULT_EXPRESSIONS;
|
||||
}
|
||||
|
||||
try {
|
||||
if (extension_settings.expressions.local) {
|
||||
const apiResult = await fetch('/api/extra/classify/labels', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
});
|
||||
|
||||
if (apiResult.ok) {
|
||||
const data = await apiResult.json();
|
||||
expressionsList = data.labels;
|
||||
return expressionsList;
|
||||
}
|
||||
} else {
|
||||
if (extension_settings.expressions.api == EXPRESSION_API.extras) {
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/classify/labels';
|
||||
|
||||
|
@ -1204,6 +1278,17 @@ async function getExpressionsList() {
|
|||
|
||||
if (apiResult.ok) {
|
||||
|
||||
const data = await apiResult.json();
|
||||
expressionsList = data.labels;
|
||||
return expressionsList;
|
||||
}
|
||||
} else {
|
||||
const apiResult = await fetch('/api/extra/classify/labels', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
});
|
||||
|
||||
if (apiResult.ok) {
|
||||
const data = await apiResult.json();
|
||||
expressionsList = data.labels;
|
||||
return expressionsList;
|
||||
|
@ -1444,6 +1529,16 @@ async function onClickExpressionRemoveCustom() {
|
|||
moduleWorker();
|
||||
}
|
||||
|
||||
function onExperesionApiChanged() {
|
||||
const tempApi = this.value;
|
||||
if (tempApi) {
|
||||
extension_settings.expressions.api = Number(tempApi);
|
||||
$('.expression_llm_prompt_block').toggle(extension_settings.expressions.api === EXPRESSION_API.llm);
|
||||
moduleWorker();
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
}
|
||||
|
||||
function onExpressionFallbackChanged() {
|
||||
const expression = this.value;
|
||||
if (expression) {
|
||||
|
@ -1556,6 +1651,7 @@ async function onClickExpressionOverrideButton() {
|
|||
|
||||
// Refresh sprites list. Assume the override path has been properly handled.
|
||||
try {
|
||||
inApiCall = true;
|
||||
$('#visual-novel-wrapper').empty();
|
||||
await validateImages(overridePath.length === 0 ? currentLastMessage.name : overridePath, true);
|
||||
const expression = await getExpressionLabel(currentLastMessage.mes);
|
||||
|
@ -1563,6 +1659,8 @@ async function onClickExpressionOverrideButton() {
|
|||
forceUpdateVisualNovelMode();
|
||||
} catch (error) {
|
||||
console.debug(`Setting expression override for ${avatarFileName} failed with error: ${error}`);
|
||||
} finally {
|
||||
inApiCall = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1699,6 +1797,22 @@ async function fetchImagesNoCache() {
|
|||
return await Promise.allSettled(promises);
|
||||
}
|
||||
|
||||
function migrateSettings() {
|
||||
if (Object.keys(extension_settings.expressions).includes('local')) {
|
||||
if (extension_settings.expressions.local) {
|
||||
extension_settings.expressions.api = EXPRESSION_API.local;
|
||||
}
|
||||
|
||||
delete extension_settings.expressions.local;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
if (extension_settings.expressions.llmPrompt === undefined) {
|
||||
extension_settings.expressions.llmPrompt = DEFAULT_LLM_PROMPT;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
function addExpressionImage() {
|
||||
const html = `
|
||||
|
@ -1730,11 +1844,6 @@ async function fetchImagesNoCache() {
|
|||
extension_settings.expressions.translate = !!$(this).prop('checked');
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
$('#expression_local').prop('checked', extension_settings.expressions.local).on('input', function () {
|
||||
extension_settings.expressions.local = !!$(this).prop('checked');
|
||||
moduleWorker();
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
$('#expression_override_cleanup_button').on('click', onClickExpressionOverrideRemoveAllButton);
|
||||
$(document).on('dragstart', '.expression', (e) => {
|
||||
e.preventDefault();
|
||||
|
@ -1753,10 +1862,23 @@ async function fetchImagesNoCache() {
|
|||
});
|
||||
|
||||
await renderAdditionalExpressionSettings();
|
||||
$('#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').val(extension_settings.expressions.llmPrompt ?? '');
|
||||
$('#expression_llm_prompt').on('input', function () {
|
||||
extension_settings.expressions.llmPrompt = $(this).val();
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
$('#expression_llm_prompt_restore').on('click', function () {
|
||||
$('#expression_llm_prompt').val(DEFAULT_LLM_PROMPT);
|
||||
extension_settings.expressions.llmPrompt = DEFAULT_LLM_PROMPT;
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$('#expression_custom_add').on('click', onClickExpressionAddCustom);
|
||||
$('#expression_custom_remove').on('click', onClickExpressionRemoveCustom);
|
||||
$('#expression_fallback').on('change', onExpressionFallbackChanged);
|
||||
$('#expression_api').on('change', onExperesionApiChanged);
|
||||
}
|
||||
|
||||
// Pause Talkinghead to save resources when the ST tab is not visible or the window is minimized.
|
||||
|
@ -1789,6 +1911,7 @@ async function fetchImagesNoCache() {
|
|||
|
||||
addExpressionImage();
|
||||
addVisualNovelMode();
|
||||
migrateSettings();
|
||||
await addSettings();
|
||||
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
||||
const updateFunction = wrapper.update.bind(wrapper);
|
||||
|
@ -1828,6 +1951,7 @@ async function fetchImagesNoCache() {
|
|||
});
|
||||
eventSource.on(event_types.MOVABLE_PANELS_RESET, updateVisualNovelModeDebounced);
|
||||
eventSource.on(event_types.GROUP_UPDATED, updateVisualNovelModeDebounced);
|
||||
eventSource.on(event_types.TEXT_COMPLETION_SETTINGS_READY, onTextGenSettingsReady);
|
||||
registerSlashCommand('sprite', setSpriteSlashCommand, ['emote'], '<span class="monospace">(spriteId)</span> – force sets the sprite for the current character', true, true);
|
||||
registerSlashCommand('spriteoverride', setSpriteSetCommand, ['costume'], '<span class="monospace">(optional folder)</span> – sets an override sprite folder for the current character. If the name starts with a slash or a backslash, selects a sub-folder in the character-named folder. Empty value to reset to default.', true, true);
|
||||
registerSlashCommand('lastsprite', (_, value) => lastExpression[value.trim()] ?? '', [], '<span class="monospace">(charName)</span> – Returns the last set sprite / expression for the named character.', true, true);
|
||||
|
|
|
@ -6,10 +6,6 @@
|
|||
</div>
|
||||
|
||||
<div class="inline-drawer-content">
|
||||
<label class="checkbox_label" for="expression_local" title="Use classification model without the Extras server.">
|
||||
<input id="expression_local" type="checkbox" />
|
||||
<span data-i18n="Local server classification">Local server classification</span>
|
||||
</label>
|
||||
<label class="checkbox_label" for="expression_translate" title="Use the selected API from Chat Translation extension settings.">
|
||||
<input id="expression_translate" type="checkbox">
|
||||
<span>Translate text to English before classification</span>
|
||||
|
@ -22,6 +18,25 @@
|
|||
<input id="image_type_toggle" type="checkbox">
|
||||
<span>Image Type - talkinghead (extras)</span>
|
||||
</label>
|
||||
<div class="expression_api_block m-b-1 m-t-1">
|
||||
<label for="expression_api">Classifier API</label>
|
||||
<small>Select the API for classifying expressions.</small>
|
||||
<select id="expression_api" class="flex1 margin0" data-i18n="Expression API" placeholder="Expression API">
|
||||
<option value="0">Local</option>
|
||||
<option value="1">Extras</option>
|
||||
<option value="2">LLM</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="expression_llm_prompt_block m-b-1 m-t-1">
|
||||
<label for="expression_llm_prompt" class="title_restorable">
|
||||
<span>LLM Prompt</span>
|
||||
<div id="expression_llm_prompt_restore" title="Restore default value" class="right_menu_button">
|
||||
<i class="fa-solid fa-clock-rotate-left fa-sm"></i>
|
||||
</div>
|
||||
</label>
|
||||
<small>Will be used if the API doesn't support JSON schemas.</small>
|
||||
<textarea id="expression_llm_prompt" type="text" class="text_pole textarea_compact" rows="2" placeholder="Use {{labels}} special macro."></textarea>
|
||||
</div>
|
||||
<div class="expression_fallback_block m-b-1 m-t-1">
|
||||
<label for="expression_fallback">Default / Fallback Expression</label>
|
||||
<small>Set the default and fallback expression being used when no matching expression is found.</small>
|
||||
|
|
|
@ -214,6 +214,7 @@ const default_settings = {
|
|||
top_a_openai: 1,
|
||||
repetition_penalty_openai: 1,
|
||||
stream_openai: false,
|
||||
websearch_cohere: false,
|
||||
openai_max_context: max_4k,
|
||||
openai_max_tokens: 300,
|
||||
wrap_in_quotes: false,
|
||||
|
@ -285,6 +286,7 @@ const oai_settings = {
|
|||
top_a_openai: 1,
|
||||
repetition_penalty_openai: 1,
|
||||
stream_openai: false,
|
||||
websearch_cohere: false,
|
||||
openai_max_context: max_4k,
|
||||
openai_max_tokens: 300,
|
||||
wrap_in_quotes: false,
|
||||
|
@ -1764,6 +1766,7 @@ async function sendOpenAIRequest(type, messages, signal) {
|
|||
generate_data['frequency_penalty'] = Math.min(Math.max(Number(oai_settings.freq_pen_openai), 0), 1);
|
||||
generate_data['presence_penalty'] = Math.min(Math.max(Number(oai_settings.pres_pen_openai), 0), 1);
|
||||
generate_data['stop'] = getCustomStoppingStrings(5);
|
||||
generate_data['websearch'] = oai_settings.websearch_cohere;
|
||||
}
|
||||
|
||||
if ((isOAI || isOpenRouter || isMistral || isCustom || isCohere) && oai_settings.seed >= 0) {
|
||||
|
@ -2611,6 +2614,7 @@ function loadOpenAISettings(data, settings) {
|
|||
oai_settings.min_p_openai = settings.min_p_openai ?? default_settings.min_p_openai;
|
||||
oai_settings.repetition_penalty_openai = settings.repetition_penalty_openai ?? default_settings.repetition_penalty_openai;
|
||||
oai_settings.stream_openai = settings.stream_openai ?? default_settings.stream_openai;
|
||||
oai_settings.websearch_cohere = settings.websearch_cohere ?? default_settings.websearch_cohere;
|
||||
oai_settings.openai_max_context = settings.openai_max_context ?? default_settings.openai_max_context;
|
||||
oai_settings.openai_max_tokens = settings.openai_max_tokens ?? default_settings.openai_max_tokens;
|
||||
oai_settings.bias_preset_selected = settings.bias_preset_selected ?? default_settings.bias_preset_selected;
|
||||
|
@ -2674,6 +2678,7 @@ function loadOpenAISettings(data, settings) {
|
|||
if (settings.use_makersuite_sysprompt !== undefined) oai_settings.use_makersuite_sysprompt = !!settings.use_makersuite_sysprompt;
|
||||
if (settings.use_alt_scale !== undefined) { oai_settings.use_alt_scale = !!settings.use_alt_scale; updateScaleForm(); }
|
||||
$('#stream_toggle').prop('checked', oai_settings.stream_openai);
|
||||
$('#websearch_toggle').prop('checked', oai_settings.websearch_cohere);
|
||||
$('#api_url_scale').val(oai_settings.api_url_scale);
|
||||
$('#openai_proxy_password').val(oai_settings.proxy_password);
|
||||
$('#claude_assistant_prefill').val(oai_settings.assistant_prefill);
|
||||
|
@ -2972,6 +2977,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
|
|||
personality_format: settings.personality_format,
|
||||
group_nudge_prompt: settings.group_nudge_prompt,
|
||||
stream_openai: settings.stream_openai,
|
||||
websearch_cohere: settings.websearch_cohere,
|
||||
prompts: settings.prompts,
|
||||
prompt_order: settings.prompt_order,
|
||||
api_url_scale: settings.api_url_scale,
|
||||
|
@ -3350,6 +3356,7 @@ function onSettingsPresetChange() {
|
|||
personality_format: ['#personality_format_textarea', 'personality_format', false],
|
||||
group_nudge_prompt: ['#group_nudge_prompt_textarea', 'group_nudge_prompt', false],
|
||||
stream_openai: ['#stream_toggle', 'stream_openai', true],
|
||||
websearch_cohere: ['#websearch_toggle', 'websearch_cohere', true],
|
||||
prompts: ['', 'prompts', false],
|
||||
prompt_order: ['', 'prompt_order', false],
|
||||
api_url_scale: ['#api_url_scale', 'api_url_scale', false],
|
||||
|
@ -4171,8 +4178,7 @@ $('#delete_proxy').on('click', async function () {
|
|||
|
||||
function runProxyCallback(_, value) {
|
||||
if (!value) {
|
||||
toastr.warning('Proxy preset name is required');
|
||||
return '';
|
||||
return selected_proxy?.name || '';
|
||||
}
|
||||
|
||||
const proxyNames = proxies.map(preset => preset.name);
|
||||
|
@ -4272,6 +4278,11 @@ $(document).ready(async function () {
|
|||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$('#websearch_toggle').on('change', function () {
|
||||
oai_settings.websearch_cohere = !!$('#websearch_toggle').prop('checked');
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$('#wrap_in_quotes').on('change', function () {
|
||||
oai_settings.wrap_in_quotes = !!$('#wrap_in_quotes').prop('checked');
|
||||
saveSettingsDebounced();
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
event_types,
|
||||
getRequestHeaders,
|
||||
getStoppingStrings,
|
||||
main_api,
|
||||
max_context,
|
||||
saveSettingsDebounced,
|
||||
setGenerationParamsFromPreset,
|
||||
|
@ -978,6 +979,10 @@ function getModel() {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
export function isJsonSchemaSupported() {
|
||||
return settings.type === TABBY && main_api === 'textgenerationwebui';
|
||||
}
|
||||
|
||||
export function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate, isContinue, cfgValues, type) {
|
||||
const canMultiSwipe = !isContinue && !isImpersonate && type !== 'quiet';
|
||||
let params = {
|
||||
|
|
|
@ -271,8 +271,8 @@ const OLLAMA_KEYS = [
|
|||
'mirostat_eta',
|
||||
];
|
||||
|
||||
const AVATAR_WIDTH = 400;
|
||||
const AVATAR_HEIGHT = 600;
|
||||
const AVATAR_WIDTH = 512;
|
||||
const AVATAR_HEIGHT = 768;
|
||||
|
||||
const OPENROUTER_HEADERS = {
|
||||
'HTTP-Referer': 'https://sillytavern.app',
|
||||
|
|
|
@ -567,6 +567,13 @@ async function sendCohereRequest(request, response) {
|
|||
|
||||
try {
|
||||
const convertedHistory = convertCohereMessages(request.body.messages, request.body.char_name, request.body.user_name);
|
||||
const connectors = [];
|
||||
|
||||
if (request.body.websearch) {
|
||||
connectors.push({
|
||||
id: 'web-search',
|
||||
});
|
||||
}
|
||||
|
||||
// https://docs.cohere.com/reference/chat
|
||||
const requestBody = {
|
||||
|
@ -584,7 +591,7 @@ async function sendCohereRequest(request, response) {
|
|||
frequency_penalty: request.body.frequency_penalty,
|
||||
presence_penalty: request.body.presence_penalty,
|
||||
prompt_truncation: 'AUTO_PRESERVE_ORDER',
|
||||
connectors: [], // TODO
|
||||
connectors: connectors,
|
||||
documents: [],
|
||||
tools: [],
|
||||
tool_results: [],
|
||||
|
|
Loading…
Reference in New Issue