Merge branch 'staging' into group-join-examples

This commit is contained in:
Cohee
2024-12-20 22:32:19 +02:00
25 changed files with 440 additions and 360 deletions

View File

@@ -1,4 +1,4 @@
import { DOMPurify, Bowser } from '../lib.js';
import { DOMPurify, Bowser, slideToggle } from '../lib.js';
import {
characters,
@@ -19,6 +19,7 @@ import {
menu_type,
substituteParams,
sendTextareaMessage,
getSlideToggleOptions,
} from '../script.js';
import {
@@ -748,8 +749,8 @@ export function initRossMods() {
$(RightNavDrawerIcon).removeClass('drawerPinnedOpen');
if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
$(RightNavPanel).slideToggle(200, 'swing');
$(RightNavDrawerIcon).toggleClass('openIcon closedIcon');
slideToggle(RightNavPanel, getSlideToggleOptions());
$(RightNavDrawerIcon).toggleClass('closedIcon openIcon');
$(RightNavPanel).toggleClass('openDrawer closedDrawer');
}
}
@@ -766,8 +767,8 @@ export function initRossMods() {
$(LeftNavDrawerIcon).removeClass('drawerPinnedOpen');
if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
$(LeftNavPanel).slideToggle(200, 'swing');
$(LeftNavDrawerIcon).toggleClass('openIcon closedIcon');
slideToggle(LeftNavPanel, getSlideToggleOptions());
$(LeftNavDrawerIcon).toggleClass('closedIcon openIcon');
$(LeftNavPanel).toggleClass('openDrawer closedDrawer');
}
}
@@ -786,8 +787,8 @@ export function initRossMods() {
if ($(WorldInfo).hasClass('openDrawer') && $('.openDrawer').length > 1) {
console.debug('closing WI after lock removal');
$(WorldInfo).slideToggle(200, 'swing');
$(WIDrawerIcon).toggleClass('openIcon closedIcon');
slideToggle(WorldInfo, getSlideToggleOptions());
$(WIDrawerIcon).toggleClass('closedIcon openIcon');
$(WorldInfo).toggleClass('openDrawer closedDrawer');
}
}

View File

@@ -417,26 +417,30 @@ async function addExtensionsButtonAndMenu() {
const button = $('#extensionsMenuButton');
const dropdown = $('#extensionsMenu');
//dropdown.hide();
let isDropdownVisible = false;
let popper = Popper.createPopper(button.get(0), dropdown.get(0), {
placement: 'top-start',
});
$(button).on('click', function () {
if (dropdown.is(':visible')) {
if (isDropdownVisible) {
dropdown.fadeOut(animation_duration);
isDropdownVisible = false;
} else {
dropdown.fadeIn(animation_duration);
isDropdownVisible = true;
}
popper.update();
});
$('html').on('click', function (e) {
if (!isDropdownVisible) return;
const clickTarget = $(e.target);
const noCloseTargets = ['#sd_gen', '#extensionsMenuButton', '#roll_dice'];
if (dropdown.is(':visible') && !noCloseTargets.some(id => clickTarget.closest(id).length > 0)) {
$(dropdown).fadeOut(animation_duration);
if (!noCloseTargets.some(id => clickTarget.closest(id).length > 0)) {
dropdown.fadeOut(animation_duration);
isDropdownVisible = false;
}
});
}

View File

@@ -393,7 +393,7 @@ jQuery(async function () {
const sendButton = $(`
<div id="send_picture" class="list-group-item flex-container flexGap5">
<div class="fa-solid fa-image extensionsMenuExtensionButton"></div>
Generate Caption
<span data-i18n="Generate Caption">Generate Caption</span>
</div>`);
$('#caption_wand_container').append(sendButton);

View File

@@ -70,7 +70,6 @@
<option data-type="google" value="gemini-1.5-pro-002">gemini-1.5-pro-002</option>
<option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option>
<option data-type="google" value="gemini-1.5-pro-exp-0827">gemini-1.5-pro-exp-0827</option>
<option data-type="google" value="gemini-pro-vision">gemini-pro-vision</option>
<option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option>
<option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option>
<option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option>

View File

@@ -1,8 +1,8 @@
<div id="sd_gen" class="list-group-item flex-container flexGap5">
<div class="fa-solid fa-paintbrush extensionsMenuExtensionButton" title="Trigger Stable Diffusion" data-i18n="[title]Trigger Stable Diffusion"></div>
<span>Generate Image</span>
<span data-i18n="Generate Image">Generate Image</span>
</div>
<div id="sd_stop_gen" class="list-group-item flex-container flexGap5">
<div class="fa-solid fa-circle-stop extensionsMenuExtensionButton" title="Abort current image generation task" data-i18n="[title]Abort current image generation task"></div>
<span>Stop Image Generation</span>
<span data-i18n="Stop Image Generation">Stop Image Generation</span>
</div>

View File

@@ -319,6 +319,7 @@ const defaultSettings = {
wand_visible: false,
command_visible: false,
interactive_visible: false,
tool_visible: false,
// Stability AI settings
stability_style_preset: 'anime',
@@ -488,6 +489,7 @@ async function loadSettings() {
$('#sd_wand_visible').prop('checked', extension_settings.sd.wand_visible);
$('#sd_command_visible').prop('checked', extension_settings.sd.command_visible);
$('#sd_interactive_visible').prop('checked', extension_settings.sd.interactive_visible);
$('#sd_tool_visible').prop('checked', extension_settings.sd.tool_visible);
$('#sd_stability_style_preset').val(extension_settings.sd.stability_style_preset);
$('#sd_huggingface_model_id').val(extension_settings.sd.huggingface_model_id);
$('#sd_function_tool').prop('checked', extension_settings.sd.function_tool);
@@ -844,6 +846,11 @@ function onInteractiveVisibleInput() {
saveSettingsDebounced();
}
function onToolVisibleInput() {
extension_settings.sd.tool_visible = !!$('#sd_tool_visible').prop('checked');
saveSettingsDebounced();
}
function onClipSkipInput() {
extension_settings.sd.clip_skip = Number($('#sd_clip_skip').val());
$('#sd_clip_skip_value').val(extension_settings.sd.clip_skip);
@@ -3670,6 +3677,8 @@ function getVisibilityByInitiator(initiator) {
return !!extension_settings.sd.wand_visible;
case initiators.command:
return !!extension_settings.sd.command_visible;
case initiators.tool:
return !!extension_settings.sd.tool_visible;
default:
return false;
}
@@ -4417,6 +4426,7 @@ jQuery(async () => {
$('#sd_wand_visible').on('input', onWandVisibleInput);
$('#sd_command_visible').on('input', onCommandVisibleInput);
$('#sd_interactive_visible').on('input', onInteractiveVisibleInput);
$('#sd_tool_visible').on('input', onToolVisibleInput);
$('#sd_swap_dimensions').on('click', onSwapDimensionsClick);
$('#sd_stability_key').on('click', onStabilityKeyClick);
$('#sd_stability_style_preset').on('change', onStabilityStylePresetChange);

View File

@@ -459,25 +459,32 @@
<div class="flex-container flexFlowColumn marginTopBot5 flexGap10">
<label for="sd_wand_visible" class="checkbox_label">
<span class="flex1 flex-container alignItemsCenter">
<i class="fa-solid fa-wand-magic-sparkles"></i>
<i class="fa-solid fa-wand-magic-sparkles fa-fw"></i>
<span data-i18n="Extensions Menu">Extensions Menu</span>
</span>
<input id="sd_wand_visible" type="checkbox" />
</label>
<label for="sd_command_visible" class="checkbox_label">
<span class="flex1 flex-container alignItemsCenter">
<i class="fa-solid fa-terminal"></i>
<i class="fa-solid fa-terminal fa-fw"></i>
<span data-i18n="Slash Command">Slash Command</span>
</span>
<input id="sd_command_visible" type="checkbox" />
</label>
<label for="sd_interactive_visible" class="checkbox_label">
<span class="flex1 flex-container alignItemsCenter">
<i class="fa-solid fa-message"></i>
<i class="fa-solid fa-message fa-fw"></i>
<span data-i18n="Interactive Mode">Interactive Mode</span>
</span>
<input id="sd_interactive_visible" type="checkbox" />
</label>
<label for="sd_tool_visible" class="checkbox_label">
<span class="flex1 flex-container alignItemsCenter">
<i class="fa-solid fa-code fa-fw"></i>
<span data-i18n="Function Tool">Function Tool</span>
</span>
<input id="sd_tool_visible" type="checkbox" />
</label>
</div>
</div>
</div>

View File

@@ -516,7 +516,11 @@ export function evaluateMacros(content, env, postProcessFn) {
break;
}
content = content.replace(macro.regex, (...args) => postProcessFn(macro.replace(...args)));
try {
content = content.replace(macro.regex, (...args) => postProcessFn(macro.replace(...args)));
} catch (e) {
console.warn(`Macro content can't be replaced: ${macro.regex} in ${content}`, e);
}
}
return content;

View File

@@ -4098,13 +4098,8 @@ async function onModelChange() {
$('#openai_max_context').attr('max', max_2mil);
} else if (value.includes('gemini-1.5-flash') || value.includes('gemini-2.0-flash-exp')) {
$('#openai_max_context').attr('max', max_1mil);
} else if (value.includes('gemini-1.0-pro-vision') || value === 'gemini-pro-vision') {
$('#openai_max_context').attr('max', max_16k);
} else if (value.includes('gemini-1.0-pro') || value === 'gemini-pro') {
$('#openai_max_context').attr('max', max_32k);
} else if (value === 'text-bison-001') {
$('#openai_max_context').attr('max', max_8k);
// The ultra endpoints are possibly dead:
} else if (value.includes('gemini-1.0-ultra') || value === 'gemini-ultra') {
$('#openai_max_context').attr('max', max_32k);
} else {
@@ -4226,16 +4221,13 @@ async function onModelChange() {
if (oai_settings.max_context_unlocked) {
$('#openai_max_context').attr('max', unlocked_max);
}
else if (['command-light', 'command'].includes(oai_settings.cohere_model)) {
else if (['command-light-nightly', 'command-light', 'command'].includes(oai_settings.cohere_model)) {
$('#openai_max_context').attr('max', max_4k);
}
else if (['command-light-nightly', 'command-nightly'].includes(oai_settings.cohere_model)) {
$('#openai_max_context').attr('max', max_8k);
}
else if (oai_settings.cohere_model.includes('command-r') || ['c4ai-aya-expanse-32b'].includes(oai_settings.cohere_model)) {
else if (oai_settings.cohere_model.includes('command-r') || ['c4ai-aya-23', 'c4ai-aya-expanse-32b', 'command-nightly'].includes(oai_settings.cohere_model)) {
$('#openai_max_context').attr('max', max_128k);
}
else if (['c4ai-aya-23', 'c4ai-aya-expanse-8b'].includes(oai_settings.cohere_model)) {
else if (['c4ai-aya-23-8b', 'c4ai-aya-expanse-8b'].includes(oai_settings.cohere_model)) {
$('#openai_max_context').attr('max', max_8k);
}
else {
@@ -4787,7 +4779,6 @@ export function isImageInliningSupported() {
'gemini-1.5-pro-002',
'gemini-1.5-pro-exp-0801',
'gemini-1.5-pro-exp-0827',
'gemini-pro-vision',
'claude-3',
'claude-3-5',
'gpt-4-turbo',

View File

@@ -55,6 +55,7 @@ const {
} = textgen_types;
const LLAMACPP_DEFAULT_ORDER = [
'dry',
'top_k',
'tfs_z',
'typical_p',
@@ -1038,11 +1039,13 @@ export function parseTextgenLogprobs(token, logprobs) {
return { token, topLogprobs: candidates };
}
case LLAMACPP: {
/** @type {Record<string, number>[]} */
if (!logprobs?.length) {
return null;
}
const candidates = logprobs[0].probs.map(x => [x.tok_str, x.prob]);
const candidates = logprobs?.[0]?.probs?.map(x => [x.tok_str, x.prob]);
if (!candidates) {
return null;
}
return { token, topLogprobs: candidates };
}
default:

View File

@@ -25,6 +25,7 @@ import { isTrueBoolean } from './utils.js';
* @typedef {object} ToolInvocationResult
* @property {ToolInvocation[]} invocations Successful tool invocations
* @property {Error[]} errors Errors that occurred during tool invocation
* @property {string[]} stealthCalls Names of stealth tools that were invoked
*/
/**
@@ -36,6 +37,7 @@ import { isTrueBoolean } from './utils.js';
* @property {function} action - The action to perform when the tool is invoked.
* @property {function} [formatMessage] - A function to format the tool call message.
* @property {function} [shouldRegister] - A function to determine if the tool should be registered.
* @property {boolean} [stealth] - A tool call result will not be shown in the chat. No follow-up generation will be performed.
*/
/**
@@ -147,6 +149,12 @@ class ToolDefinition {
*/
#shouldRegister;
/**
* A tool call result will not be shown in the chat. No follow-up generation will be performed.
* @type {boolean}
*/
#stealth;
/**
* Creates a new ToolDefinition.
* @param {string} name A unique name for the tool.
@@ -156,8 +164,9 @@ class ToolDefinition {
* @param {function} action A function that will be called when the tool is executed.
* @param {function} formatMessage A function that will be called to format the tool call toast.
* @param {function} shouldRegister A function that will be called to determine if the tool should be registered.
* @param {boolean} stealth A tool call result will not be shown in the chat. No follow-up generation will be performed.
*/
constructor(name, displayName, description, parameters, action, formatMessage, shouldRegister) {
constructor(name, displayName, description, parameters, action, formatMessage, shouldRegister, stealth) {
this.#name = name;
this.#displayName = displayName;
this.#description = description;
@@ -165,6 +174,7 @@ class ToolDefinition {
this.#action = action;
this.#formatMessage = formatMessage;
this.#shouldRegister = shouldRegister;
this.#stealth = stealth;
}
/**
@@ -214,6 +224,10 @@ class ToolDefinition {
get displayName() {
return this.#displayName;
}
get stealth() {
return this.#stealth;
}
}
/**
@@ -246,7 +260,7 @@ export class ToolManager {
* Registers a new tool with the tool registry.
* @param {ToolRegistration} tool The tool to register.
*/
static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage, shouldRegister }) {
static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage, shouldRegister, stealth }) {
// Convert WIP arguments
if (typeof arguments[0] !== 'object') {
[name, description, parameters, action] = arguments;
@@ -256,7 +270,16 @@ export class ToolManager {
console.warn(`[ToolManager] A tool with the name "${name}" has already been registered. The definition will be overwritten.`);
}
const definition = new ToolDefinition(name, displayName, description, parameters, action, formatMessage, shouldRegister);
const definition = new ToolDefinition(
name,
displayName,
description,
parameters,
action,
formatMessage,
shouldRegister,
stealth,
);
this.#tools.set(name, definition);
console.log('[ToolManager] Registered function tool:', definition);
}
@@ -302,6 +325,20 @@ export class ToolManager {
}
}
/**
* Checks if a tool is a stealth tool.
* @param {string} name The name of the tool to check.
* @returns {boolean} Whether the tool is a stealth tool.
*/
static isStealthTool(name) {
if (!this.#tools.has(name)) {
return false;
}
const tool = this.#tools.get(name);
return !!tool.stealth;
}
/**
* Formats a message for a tool call by name.
* @param {string} name The name of the tool to format the message for.
@@ -608,6 +645,7 @@ export class ToolManager {
const result = {
invocations: [],
errors: [],
stealthCalls: [],
};
const toolCalls = ToolManager.#getToolCallsFromData(data);
@@ -625,7 +663,7 @@ export class ToolManager {
const parameters = toolCall.function.arguments;
const name = toolCall.function.name;
const displayName = ToolManager.getDisplayName(name);
const isStealth = ToolManager.isStealthTool(name);
const message = await ToolManager.formatToolCallMessage(name, parameters);
const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 });
const toolResult = await ToolManager.invokeFunctionTool(name, parameters);
@@ -638,6 +676,12 @@ export class ToolManager {
continue;
}
// Don't save stealth tool invocations
if (isStealth) {
result.stealthCalls.push(name);
continue;
}
const invocation = {
id,
displayName,
@@ -860,6 +904,14 @@ export class ToolManager {
isRequired: false,
acceptsMultiple: false,
}),
SlashCommandNamedArgument.fromProps({
name: 'stealth',
description: 'If true, a tool call result will not be shown in the chat and no follow-up generation will be performed.',
typeList: [ARGUMENT_TYPE.BOOLEAN],
isRequired: false,
acceptsMultiple: false,
defaultValue: String(false),
}),
],
unnamedArgumentList: [
SlashCommandArgument.fromProps({
@@ -891,7 +943,7 @@ export class ToolManager {
};
}
const { name, displayName, description, parameters, formatMessage, shouldRegister } = args;
const { name, displayName, description, parameters, formatMessage, shouldRegister, stealth } = args;
if (!(action instanceof SlashCommandClosure)) {
throw new Error('The unnamed argument must be a closure.');
@@ -927,6 +979,7 @@ export class ToolManager {
action: actionFunc,
formatMessage: formatMessageFunc,
shouldRegister: shouldRegisterFunc,
stealth: stealth && isTrueBoolean(String(stealth)),
});
return '';

View File

@@ -46,6 +46,10 @@ function getLocalVariable(name, args = {}) {
}
function setLocalVariable(name, value, args = {}) {
if (!name) {
throw new Error('Variable name cannot be empty or undefined.');
}
if (!chat_metadata.variables) {
chat_metadata.variables = {};
}
@@ -99,6 +103,10 @@ function getGlobalVariable(name, args = {}) {
}
function setGlobalVariable(name, value, args = {}) {
if (!name) {
throw new Error('Variable name cannot be empty or undefined.');
}
if (args.index !== undefined) {
try {
let globalVariable = JSON.parse(extension_settings.variables.global[name] ?? 'null');