mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
#2513 Add 'mode' argument for /fuzzy
This commit is contained in:
@ -952,14 +952,36 @@ export function initDefaultSlashCommands() {
|
|||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'fuzzy',
|
name: 'fuzzy',
|
||||||
callback: fuzzyCallback,
|
callback: fuzzyCallback,
|
||||||
returns: 'first matching item',
|
returns: 'matching item',
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
new SlashCommandNamedArgument(
|
SlashCommandNamedArgument.fromProps({
|
||||||
'list', 'list of items to match against', [ARGUMENT_TYPE.LIST], true,
|
name: 'list',
|
||||||
),
|
description: 'list of items to match against',
|
||||||
new SlashCommandNamedArgument(
|
acceptsMultiple: false,
|
||||||
'threshold', 'fuzzy match threshold (0.0 to 1.0)', [ARGUMENT_TYPE.NUMBER], false, false, '0.4',
|
isRequired: true,
|
||||||
),
|
typeList: [ARGUMENT_TYPE.LIST, ARGUMENT_TYPE.VARIABLE_NAME],
|
||||||
|
enumProvider: commonEnumProviders.variables('all'),
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'threshold',
|
||||||
|
description: 'fuzzy match threshold (0.0 to 1.0)',
|
||||||
|
typeList: [ARGUMENT_TYPE.NUMBER],
|
||||||
|
isRequired: false,
|
||||||
|
defaultValue: '0.4',
|
||||||
|
acceptsMultiple: false,
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'mode',
|
||||||
|
description: 'fuzzy match mode',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: false,
|
||||||
|
defaultValue: 'first',
|
||||||
|
acceptsMultiple: false,
|
||||||
|
enumProvider: () => [
|
||||||
|
new SlashCommandEnumValue('first', 'first match below the threshold', enumTypes.enum, enumIcons.default),
|
||||||
|
new SlashCommandEnumValue('best', 'best match below the threshold', enumTypes.enum, enumIcons.default),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
unnamedArgumentList: [
|
unnamedArgumentList: [
|
||||||
new SlashCommandArgument(
|
new SlashCommandArgument(
|
||||||
@ -976,6 +998,13 @@ export function initDefaultSlashCommands() {
|
|||||||
A low value (min 0.0) means the match is very strict.
|
A low value (min 0.0) means the match is very strict.
|
||||||
At 1.0 (max) the match is very loose and will match anything.
|
At 1.0 (max) the match is very loose and will match anything.
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
The optional <code>mode</code> argument allows to control the behavior when multiple items match the text.
|
||||||
|
<ul>
|
||||||
|
<li><code>first</code> (default) returns the first match below the threshold.</li>
|
||||||
|
<li><code>best</code> returns the best match below the threshold.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
The returned value passes to the next command through the pipe.
|
The returned value passes to the next command through the pipe.
|
||||||
</div>
|
</div>
|
||||||
@ -1865,7 +1894,7 @@ async function inputCallback(args, prompt) {
|
|||||||
* @param {FuzzyCommandArgs} args - arguments containing "list" (JSON array) and optionaly "threshold" (float between 0.0 and 1.0)
|
* @param {FuzzyCommandArgs} args - arguments containing "list" (JSON array) and optionaly "threshold" (float between 0.0 and 1.0)
|
||||||
* @param {string} searchInValue - the string where items of list are searched
|
* @param {string} searchInValue - the string where items of list are searched
|
||||||
* @returns {string} - the matched item from the list
|
* @returns {string} - the matched item from the list
|
||||||
* @typedef {{list: string, threshold: string}} FuzzyCommandArgs - arguments for /fuzzy command
|
* @typedef {{list: string, threshold: string, mode:string}} FuzzyCommandArgs - arguments for /fuzzy command
|
||||||
* @example /fuzzy list=["down","left","up","right"] "he looks up" | /echo // should return "up"
|
* @example /fuzzy list=["down","left","up","right"] "he looks up" | /echo // should return "up"
|
||||||
* @link https://www.fusejs.io/
|
* @link https://www.fusejs.io/
|
||||||
*/
|
*/
|
||||||
@ -1895,7 +1924,7 @@ function fuzzyCallback(args, searchInValue) {
|
|||||||
};
|
};
|
||||||
// threshold determines how strict is the match, low threshold value is very strict, at 1 (nearly?) everything matches
|
// threshold determines how strict is the match, low threshold value is very strict, at 1 (nearly?) everything matches
|
||||||
if ('threshold' in args) {
|
if ('threshold' in args) {
|
||||||
params.threshold = parseFloat(resolveVariable(args.threshold));
|
params.threshold = parseFloat(args.threshold);
|
||||||
if (isNaN(params.threshold)) {
|
if (isNaN(params.threshold)) {
|
||||||
console.warn('WARN: \'threshold\' argument must be a float between 0.0 and 1.0 for /fuzzy command');
|
console.warn('WARN: \'threshold\' argument must be a float between 0.0 and 1.0 for /fuzzy command');
|
||||||
return '';
|
return '';
|
||||||
@ -1908,16 +1937,42 @@ function fuzzyCallback(args, searchInValue) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFirstMatch() {
|
||||||
const fuse = new Fuse([searchInValue], params);
|
const fuse = new Fuse([searchInValue], params);
|
||||||
// each item in the "list" is searched within "search_item", if any matches it returns the matched "item"
|
// each item in the "list" is searched within "search_item", if any matches it returns the matched "item"
|
||||||
for (const searchItem of list) {
|
for (const searchItem of list) {
|
||||||
const result = fuse.search(searchItem);
|
const result = fuse.search(searchItem);
|
||||||
|
console.debug('/fuzzy: result', result);
|
||||||
if (result.length > 0) {
|
if (result.length > 0) {
|
||||||
console.info('fuzzyCallback Matched: ' + searchItem);
|
console.info('/fuzzy: first matched', searchItem);
|
||||||
return searchItem;
|
return searchItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.info('/fuzzy: no match');
|
||||||
return '';
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBestMatch() {
|
||||||
|
const fuse = new Fuse(list, params);
|
||||||
|
const result = fuse.search(searchInValue);
|
||||||
|
console.debug('/fuzzy: result', result);
|
||||||
|
if (result.length > 0) {
|
||||||
|
console.info('/fuzzy: best matched', result[0].item);
|
||||||
|
return result[0].item;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info('/fuzzy: no match');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (String(args.mode).trim().toLowerCase()) {
|
||||||
|
case 'best':
|
||||||
|
return getBestMatch();
|
||||||
|
case 'first':
|
||||||
|
default:
|
||||||
|
return getFirstMatch();
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
console.warn('WARN: Invalid list argument provided for /fuzzy command');
|
console.warn('WARN: Invalid list argument provided for /fuzzy command');
|
||||||
return '';
|
return '';
|
||||||
|
Reference in New Issue
Block a user