Merge pull request #3289 from zerofata/vector-db-search-cmd Add returnChunks and resultSize args to /db-search

b177affd81cb1c3ec7f4a259aef22b506e3a192b

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
1 files changed, +35 -3Showing whitespace changes
public/scripts/extensions/vectors/index.js+35 -3
@@ -30,6 +30,8 @@ import { textgen_types, textgenerationwebui_settings } from '../../textgen-setti
30import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';30import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
31import { SlashCommand } from '../../slash-commands/SlashCommand.js';31import { SlashCommand } from '../../slash-commands/SlashCommand.js';
32import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';32import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
33import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
34import { slashCommandReturnHelper } from '../../slash-commands/SlashCommandReturnHelper.js';
33import { callGenericPopup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js';35import { callGenericPopup, POPUP_RESULT, POPUP_TYPE } from '../../popup.js';
34import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js';36import { generateWebLlmChatPrompt, isWebLlmSupported } from '../shared.js';
3537
@@ -1613,25 +1615,55 @@ jQuery(async () => {
1613 callback: async (args, query) => {1615 callback: async (args, query) => {
1614 const clamp = (v) => Number.isNaN(v) ? null : Math.min(1, Math.max(0, v));1616 const clamp = (v) => Number.isNaN(v) ? null : Math.min(1, Math.max(0, v));
1615 const threshold = clamp(Number(args?.threshold ?? settings.score_threshold));1617 const threshold = clamp(Number(args?.threshold ?? settings.score_threshold));
1618 const validateCount = (v) => Number.isNaN(v) || !Number.isInteger(v) || v < 1 ? null : v;
1619 const count = validateCount(Number(args?.count)) ?? settings.chunk_count_db;
1616 const source = String(args?.source ?? '');1620 const source = String(args?.source ?? '');
1617 const attachments = source ? getDataBankAttachmentsForSource(source, false) : getDataBankAttachments(false);1621 const attachments = source ? getDataBankAttachmentsForSource(source, false) : getDataBankAttachments(false);
1618 const collectionIds = await ingestDataBankAttachments(String(source));1622 const collectionIds = await ingestDataBankAttachments(String(source));
1619 const queryResults = await queryMultipleCollections(collectionIds, String(query), settings.chunk_count_db, threshold);1623 const queryResults = await queryMultipleCollections(collectionIds, String(query), count, threshold);
1620 1624
1621 // Map collection IDs to file URLs1625 // Get URLs
1622 const urls = Object1626 const urls = Object
1623 .keys(queryResults)1627 .keys(queryResults)
1624 .map(x => attachments.find(y => getFileCollectionId(y.url) === x))1628 .map(x => attachments.find(y => getFileCollectionId(y.url) === x))
1625 .filter(x => x)1629 .filter(x => x)
1626 .map(x => x.url);1630 .map(x => x.url);
1627 1631
1628 return JSON.stringify(urls);1632 // Gets the actual text content of chunks
1633 const getChunksText = () => {
1634 let textResult = '';
1635 for (const collectionId in queryResults) {
1636 const metadata = queryResults[collectionId].metadata?.filter(x => x.text)?.sort((a, b) => a.index - b.index)?.map(x => x.text)?.filter(onlyUnique) || [];
1637 textResult += metadata.join('\n') + '\n\n';
1638 }
1639 return textResult;
1640 };
1641
1642 if (args.return === 'chunks') {
1643 return getChunksText();
1644 }
1645
1646 // @ts-ignore
1647 return slashCommandReturnHelper.doReturn(args.return ?? 'object', urls, { objectToStringFunc: list => list.join('\n') });
1648
1629 },1649 },
1630 aliases: ['databank-search', 'data-bank-search'],1650 aliases: ['databank-search', 'data-bank-search'],
1631 helpString: 'Search the Data Bank for a specific query using vector similarity. Returns a list of file URLs with the most relevant content.',1651 helpString: 'Search the Data Bank for a specific query using vector similarity. Returns a list of file URLs with the most relevant content.',
1632 namedArgumentList: [1652 namedArgumentList: [
1633 new SlashCommandNamedArgument('threshold', 'Threshold for the similarity score in the [0, 1] range. Uses the global config value if not set.', ARGUMENT_TYPE.NUMBER, false, false, ''),1653 new SlashCommandNamedArgument('threshold', 'Threshold for the similarity score in the [0, 1] range. Uses the global config value if not set.', ARGUMENT_TYPE.NUMBER, false, false, ''),
1654 new SlashCommandNamedArgument('count', 'Maximum number of query results to return.', ARGUMENT_TYPE.NUMBER, false, false, ''),
1634 new SlashCommandNamedArgument('source', 'Optional filter for the attachments by source.', ARGUMENT_TYPE.STRING, false, false, '', ['global', 'character', 'chat']),1655 new SlashCommandNamedArgument('source', 'Optional filter for the attachments by source.', ARGUMENT_TYPE.STRING, false, false, '', ['global', 'character', 'chat']),
1656 SlashCommandNamedArgument.fromProps({
1657 name: 'return',
1658 description: 'How you want the return value to be provided',
1659 typeList: [ARGUMENT_TYPE.STRING],
1660 defaultValue: 'object',
1661 enumList: [
1662 new SlashCommandEnumValue('chunks', 'Return the actual content chunks', enumTypes.enum, '{}'),
1663 ...slashCommandReturnHelper.enumList({ allowObject: true })
1664 ],
1665 forceEnum: true,
1666 })
1635 ],1667 ],
1636 unnamedArgumentList: [1668 unnamedArgumentList: [
1637 new SlashCommandArgument('Query to search by.', ARGUMENT_TYPE.STRING, true, false),1669 new SlashCommandArgument('Query to search by.', ARGUMENT_TYPE.STRING, true, false),