From e753cdf0fb8b8c01ab8fc90e1788502d5f6668e3 Mon Sep 17 00:00:00 2001 From: Stefan Daniel Schwarz Date: Thu, 18 Apr 2024 23:14:15 +0200 Subject: [PATCH 01/24] Llama 3 Instruct context+instruct presets --- .../presets/context/Llama 3 Instruct.json | 12 ++++++++++ .../presets/instruct/Llama 3 Instruct.json | 24 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 default/content/presets/context/Llama 3 Instruct.json create mode 100644 default/content/presets/instruct/Llama 3 Instruct.json diff --git a/default/content/presets/context/Llama 3 Instruct.json b/default/content/presets/context/Llama 3 Instruct.json new file mode 100644 index 000000000..76fef1490 --- /dev/null +++ b/default/content/presets/context/Llama 3 Instruct.json @@ -0,0 +1,12 @@ +{ + "story_string": "<|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n\n<|eot_id|>\n", + "example_separator": "\n<|start_header_id|>system<|end_header_id|>\n\nExample Chat:<|eot_id|>\n", + "chat_start": "\n<|start_header_id|>system<|end_header_id|>\n\nNew Chat:<|eot_id|>\n", + "use_stop_strings": false, + "allow_jailbreak": false, + "always_force_name2": true, + "trim_sentences": false, + "include_newline": false, + "single_line": false, + "name": "Llama 3 Instruct" +} \ No newline at end of file diff --git a/default/content/presets/instruct/Llama 3 Instruct.json b/default/content/presets/instruct/Llama 3 Instruct.json new file mode 100644 index 000000000..f9041752a --- /dev/null +++ b/default/content/presets/instruct/Llama 3 Instruct.json @@ -0,0 +1,24 @@ +{ + "system_prompt": "Write {{char}}'s next reply in this fictional roleplay with {{user}}.", + "input_sequence": "<|start_header_id|>user<|end_header_id|>\n\n", + "output_sequence": "<|start_header_id|>assistant<|end_header_id|>\n\n", + "last_output_sequence": "", + "system_sequence": "<|start_header_id|>system<|end_header_id|>\n\n", + "stop_sequence": "<|end_of_text|>", + "wrap": false, + "macro": true, + "names": true, + "names_force_groups": true, + "activation_regex": "", + "system_sequence_prefix": "", + "system_sequence_suffix": "", + "first_output_sequence": "", + "skip_examples": false, + "output_suffix": "<|eot_id|>\n\n", + "input_suffix": "<|eot_id|>\n\n", + "system_suffix": "<|eot_id|>\n\n", + "user_alignment_message": "", + "system_same_as_user": false, + "last_system_sequence": "", + "name": "Llama 3 Instruct" +} \ No newline at end of file From 8cf116754d83ef3a059715ea102d6713d83295fe Mon Sep 17 00:00:00 2001 From: Stefan Daniel Schwarz Date: Thu, 18 Apr 2024 23:20:24 +0200 Subject: [PATCH 02/24] Update content index --- default/content/index.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/default/content/index.json b/default/content/index.json index f0339189d..d4ef03cb6 100644 --- a/default/content/index.json +++ b/default/content/index.json @@ -432,6 +432,10 @@ "filename": "presets/context/Command R.json", "type": "context" }, + { + "filename": "presets/context/Llama 3 Instruct.json", + "type": "context" + }, { "filename": "presets/instruct/Adventure.json", "type": "instruct" @@ -519,5 +523,9 @@ { "filename": "presets/instruct/Command R.json", "type": "instruct" + }, + { + "filename": "presets/instruct/Llama 3 Instruct.json", + "type": "instruct" } ] From 48fd9c23fb264e0a4b1700606e832fb1eabb304c Mon Sep 17 00:00:00 2001 From: Stefan Daniel Schwarz Date: Thu, 18 Apr 2024 23:26:40 +0200 Subject: [PATCH 03/24] Llama 3 Instruct fix stop sequence --- default/content/presets/instruct/Llama 3 Instruct.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default/content/presets/instruct/Llama 3 Instruct.json b/default/content/presets/instruct/Llama 3 Instruct.json index f9041752a..b3966b64b 100644 --- a/default/content/presets/instruct/Llama 3 Instruct.json +++ b/default/content/presets/instruct/Llama 3 Instruct.json @@ -4,7 +4,7 @@ "output_sequence": "<|start_header_id|>assistant<|end_header_id|>\n\n", "last_output_sequence": "", "system_sequence": "<|start_header_id|>system<|end_header_id|>\n\n", - "stop_sequence": "<|end_of_text|>", + "stop_sequence": "<|eot_id|>", "wrap": false, "macro": true, "names": true, From 8467ba38441a18e184fe1492d49faed54fb675ce Mon Sep 17 00:00:00 2001 From: Stefan Daniel Schwarz Date: Fri, 19 Apr 2024 00:54:14 +0200 Subject: [PATCH 04/24] Llama 3 Instruct remove newlines after eot_id --- default/content/presets/context/Llama 3 Instruct.json | 6 +++--- default/content/presets/instruct/Llama 3 Instruct.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/default/content/presets/context/Llama 3 Instruct.json b/default/content/presets/context/Llama 3 Instruct.json index 76fef1490..661aba837 100644 --- a/default/content/presets/context/Llama 3 Instruct.json +++ b/default/content/presets/context/Llama 3 Instruct.json @@ -1,7 +1,7 @@ { - "story_string": "<|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n\n<|eot_id|>\n", - "example_separator": "\n<|start_header_id|>system<|end_header_id|>\n\nExample Chat:<|eot_id|>\n", - "chat_start": "\n<|start_header_id|>system<|end_header_id|>\n\nNew Chat:<|eot_id|>\n", + "story_string": "<|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n\n<|eot_id|>", + "example_separator": "\n<|start_header_id|>system<|end_header_id|>\n\nExample Chat:<|eot_id|>", + "chat_start": "\n<|start_header_id|>system<|end_header_id|>\n\nNew Chat:<|eot_id|>", "use_stop_strings": false, "allow_jailbreak": false, "always_force_name2": true, diff --git a/default/content/presets/instruct/Llama 3 Instruct.json b/default/content/presets/instruct/Llama 3 Instruct.json index b3966b64b..786540fec 100644 --- a/default/content/presets/instruct/Llama 3 Instruct.json +++ b/default/content/presets/instruct/Llama 3 Instruct.json @@ -14,9 +14,9 @@ "system_sequence_suffix": "", "first_output_sequence": "", "skip_examples": false, - "output_suffix": "<|eot_id|>\n\n", - "input_suffix": "<|eot_id|>\n\n", - "system_suffix": "<|eot_id|>\n\n", + "output_suffix": "<|eot_id|>", + "input_suffix": "<|eot_id|>", + "system_suffix": "<|eot_id|>", "user_alignment_message": "", "system_same_as_user": false, "last_system_sequence": "", From 794786da434ac959af091d07207e2ffd67afc1b0 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 02:08:18 +0300 Subject: [PATCH 05/24] Remove unnecessary delays in the prompt builder. This is no longer needed since the async token counter won't block the UI thread during the request preparation. --- public/script.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/public/script.js b/public/script.js index a10f4d1fa..13be91c6f 100644 --- a/public/script.js +++ b/public/script.js @@ -3521,9 +3521,6 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu } else { break; } - - // Prevent UI thread lock on tokenization - await delay(1); } for (let i = 0; i < chat2.length; i++) { @@ -3551,9 +3548,6 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu } else { break; } - - // Prevent UI thread lock on tokenization - await delay(1); } // Add user alignment message if last message is not a user message @@ -3596,7 +3590,6 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu } else { break; } - await delay(1); } } From 8dc30e9da3784aaf6ff3b77366cc99f8fd825580 Mon Sep 17 00:00:00 2001 From: Stefan Daniel Schwarz Date: Fri, 19 Apr 2024 09:50:02 +0200 Subject: [PATCH 06/24] Llama 3 Instruct remove newlines before eot_id in story string --- default/content/presets/context/Llama 3 Instruct.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default/content/presets/context/Llama 3 Instruct.json b/default/content/presets/context/Llama 3 Instruct.json index 661aba837..282f7fcc5 100644 --- a/default/content/presets/context/Llama 3 Instruct.json +++ b/default/content/presets/context/Llama 3 Instruct.json @@ -1,5 +1,5 @@ { - "story_string": "<|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}\n\n<|eot_id|>", + "story_string": "<|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}<|eot_id|>", "example_separator": "\n<|start_header_id|>system<|end_header_id|>\n\nExample Chat:<|eot_id|>", "chat_start": "\n<|start_header_id|>system<|end_header_id|>\n\nNew Chat:<|eot_id|>", "use_stop_strings": false, From 39b305621e0446cbca0825e5ab50f3859616e6a1 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:35:08 +0900 Subject: [PATCH 07/24] reduce .mes top-margin on flat chat --- public/style.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/public/style.css b/public/style.css index 98bf16c5d..22898249f 100644 --- a/public/style.css +++ b/public/style.css @@ -157,6 +157,7 @@ body { border-top: 20px solid transparent; min-height: 40px; } + ::-webkit-scrollbar-thumb:horizontal { background-color: var(--grey7070a); box-shadow: inset 0 0 0 1px var(--black50a); @@ -799,7 +800,7 @@ body .panelControlBar { .mes { display: flex; align-items: flex-start; - padding: 20px 10px 0 10px; + padding: 10px 10px 0 10px; margin-top: 0; width: 100%; color: var(--SmartThemeBodyColor); @@ -2240,7 +2241,8 @@ grammarly-extension { margin-right: 25px; } -#shadow_popup, .shadow_popup { +#shadow_popup, +.shadow_popup { backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2)); -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2)); background-color: var(--black30a); @@ -2252,6 +2254,7 @@ grammarly-extension { height: 100svh; z-index: 9999; top: 0; + &.shadow_popup { z-index: 9998; } @@ -4010,4 +4013,4 @@ body:not(.movingUI) .drawer-content.maximized { height: 100vh; z-index: 9999; } -} +} \ No newline at end of file From 41a4de7224be7ae2b50728626fa68c6e15bad48e Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 13:35:36 +0300 Subject: [PATCH 08/24] Limit slash autocomplete --- public/scripts/slash-commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index b403205e9..46ecdc9ac 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -1833,7 +1833,7 @@ function setSlashCommandAutocomplete(textarea) { .keys(parser.helpStrings) // Get all slash commands .filter(x => x.startsWith(slashCommand)) // Filter by the input .sort((a, b) => a.localeCompare(b)) // Sort alphabetically - // .slice(0, 20) // Limit to 20 results + .slice(0, 5) // Limit to 5 results .map(x => ({ label: parser.helpStrings[x], value: `/${x} ` })); // Map to the help string output(result); // Return the results From 4a5d9528000b483922d5592065d4e1320a899963 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:19:57 +0300 Subject: [PATCH 09/24] Fix script comments. Add type hints --- public/scripts/slash-commands.js | 66 ++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 46ecdc9ac..76e9138ef 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -50,10 +50,18 @@ import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCoun import { delay, isFalseBoolean, isTrueBoolean, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; import { registerVariableCommands, resolveVariable } from './variables.js'; import { background_settings } from './backgrounds.js'; -export { - executeSlashCommands, getSlashCommandsHelp, registerSlashCommand, -}; +/** + * @typedef {object} SlashCommand + * @property {function} callback - The callback function to execute + * @property {string} helpString - The help string for the command + * @property {boolean} interruptsGeneration - Whether the command interrupts message generation + * @property {boolean} purgeFromMessage - Whether the command should be purged from the message + */ + +/** + * Provides a parser for slash commands. + */ class SlashCommandParser { static COMMENT_KEYWORDS = ['#', '/']; static RESERVED_KEYWORDS = [ @@ -61,10 +69,26 @@ class SlashCommandParser { ]; constructor() { + /** + * @type {Record} - Slash commands registered in the parser + */ this.commands = {}; + /** + * @type {Record} - Help strings for each command + */ this.helpStrings = {}; } + /** + * Adds a slash command to the parser. + * @param {string} command - The command name + * @param {function} callback - The callback function to execute + * @param {string[]} aliases - The command aliases + * @param {string} helpString - The help string for the command + * @param {boolean} [interruptsGeneration] - Whether the command interrupts message generation + * @param {boolean} [purgeFromMessage] - Whether the command should be purged from the message + * @returns {void} + */ addCommand(command, callback, aliases, helpString = '', interruptsGeneration = false, purgeFromMessage = true) { const fnObj = { callback, helpString, interruptsGeneration, purgeFromMessage }; @@ -96,7 +120,7 @@ class SlashCommandParser { /** * Parses a slash command to extract the command name, the (named) arguments and the remaining text * @param {string} text - Slash command text - * @returns {{command: string, args: object, value: string}} - The parsed command, its arguments and the remaining text + * @returns {{command: SlashCommand, args: object, value: string, commandName: string}} - The parsed command, its arguments and the remaining text */ parse(text) { // Parses a command even when spaces are present in arguments @@ -118,6 +142,20 @@ class SlashCommandParser { console.debug('command:' + command); } + if (SlashCommandParser.COMMENT_KEYWORDS.includes(command)) { + return { + commandName: command, + command: { + callback: () => {}, + helpString: '', + interruptsGeneration: false, + purgeFromMessage: true, + }, + args: {}, + value: '', + }; + } + // parse the rest of the string to extract named arguments, the remainder is the "unnamedArg" which is usually text, like the prompt to send while (remainingText.length > 0) { // does the remaining text is like nameArg=[value] or nameArg=[value,value] or nameArg=[ value , value , value] @@ -176,7 +214,7 @@ class SlashCommandParser { // your weird complex command is now transformed into a juicy tiny text or something useful :) if (this.commands[command]) { - return { command: this.commands[command], args: argObj, value: unnamedArg }; + return { command: this.commands[command], args: argObj, value: unnamedArg, commandName: command }; } return null; @@ -197,8 +235,13 @@ class SlashCommandParser { } const parser = new SlashCommandParser(); -const registerSlashCommand = parser.addCommand.bind(parser); -const getSlashCommandsHelp = parser.getHelpString.bind(parser); + +/** + * Registers a slash command in the parser. +* @type {(command: string, callback: function, aliases: string[], helpString: string, interruptsGeneration?: boolean, purgeFromMessage?: boolean) => void} +*/ +export const registerSlashCommand = parser.addCommand.bind(parser); +export const getSlashCommandsHelp = parser.getHelpString.bind(parser); parser.addCommand('?', helpCommandCallback, ['help'], ' – get help on macros, chat formatting and commands', true, true); parser.addCommand('name', setNameCallback, ['persona'], '(name) – sets user name and persona avatar (if set)', true, true); @@ -1293,7 +1336,7 @@ export async function generateSystemMessage(_, prompt) { // Generate and regex the output if applicable toastr.info('Please wait', 'Generating...'); - let message = await generateQuietPrompt(prompt); + let message = await generateQuietPrompt(prompt, false, false); message = getRegexedString(message, regex_placement.SLASH_COMMAND); sendNarratorMessage(_, message); @@ -1485,7 +1528,7 @@ export async function promptQuietForLoudResponse(who, text) { //text = `${text}${power_user.instruct.enabled ? '' : '\n'}${(power_user.always_force_name2 && who != 'raw') ? characters[character_id].name + ":" : ""}` - let reply = await generateQuietPrompt(text, true); + let reply = await generateQuietPrompt(text, true, false); text = await getRegexedString(reply, regex_placement.SLASH_COMMAND); const message = { @@ -1717,7 +1760,7 @@ function modelCallback(_, model) { * @param {boolean} unescape Whether to unescape the batch separator * @returns {Promise<{interrupt: boolean, newText: string, pipe: string} | boolean>} */ -async function executeSlashCommands(text, unescape = false) { +export async function executeSlashCommands(text, unescape = false) { if (!text) { return false; } @@ -1758,7 +1801,8 @@ async function executeSlashCommands(text, unescape = false) { } // Skip comment commands. They don't run macros or interrupt pipes. - if (SlashCommandParser.COMMENT_KEYWORDS.includes(result.command)) { + if (SlashCommandParser.COMMENT_KEYWORDS.includes(result.commandName)) { + result.command.purgeFromMessage && linesToRemove.push(lines[index]); continue; } From db3d86cb29301cd0d1df2fd994a9e0dcf46e8f1a Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Fri, 19 Apr 2024 21:02:02 +0900 Subject: [PATCH 10/24] optimize slash command helper popup --- public/scripts/slash-commands.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index b403205e9..25e45039b 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -1822,8 +1822,8 @@ async function executeSlashCommands(text, unescape = false) { function setSlashCommandAutocomplete(textarea) { textarea.autocomplete({ source: (input, output) => { - // Only show for slash commands and if there's no space - if (!input.term.startsWith('/') || input.term.includes(' ')) { + // Only show for slash commands (requiring at least 1 letter after the slash) and if there's no space + if (!input.term.startsWith('/') || input.term.includes(' ') || input.term === '/') { output([]); return; } From d5666ab01be3e94770cb793df83aa50d9cd3e476 Mon Sep 17 00:00:00 2001 From: Stefan Daniel Schwarz Date: Fri, 19 Apr 2024 16:19:53 +0200 Subject: [PATCH 11/24] Llama 3 Instruct remove chat and example headers --- default/content/presets/context/Llama 3 Instruct.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/default/content/presets/context/Llama 3 Instruct.json b/default/content/presets/context/Llama 3 Instruct.json index 282f7fcc5..62bbd0753 100644 --- a/default/content/presets/context/Llama 3 Instruct.json +++ b/default/content/presets/context/Llama 3 Instruct.json @@ -1,7 +1,7 @@ { "story_string": "<|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{char}}'s personality: {{personality}}\n{{/if}}{{#if scenario}}Scenario: {{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}<|eot_id|>", - "example_separator": "\n<|start_header_id|>system<|end_header_id|>\n\nExample Chat:<|eot_id|>", - "chat_start": "\n<|start_header_id|>system<|end_header_id|>\n\nNew Chat:<|eot_id|>", + "example_separator": "", + "chat_start": "", "use_stop_strings": false, "allow_jailbreak": false, "always_force_name2": true, From 19ea1ee56cb9bdc9566cae5504b29280d4bd9710 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:41:40 +0300 Subject: [PATCH 12/24] Fix field style --- public/scripts/extensions/attachments/manager.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/extensions/attachments/manager.html b/public/scripts/extensions/attachments/manager.html index 94d2b4d4b..4872e805f 100644 --- a/public/scripts/extensions/attachments/manager.html +++ b/public/scripts/extensions/attachments/manager.html @@ -12,7 +12,7 @@
- From a3f6ce52e431b7f9a883e3d4800ab133921def0e Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:43:35 +0300 Subject: [PATCH 13/24] Fix manual vectorization of files --- public/scripts/extensions/vectors/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/public/scripts/extensions/vectors/index.js b/public/scripts/extensions/vectors/index.js index 3d6238b11..d228326f1 100644 --- a/public/scripts/extensions/vectors/index.js +++ b/public/scripts/extensions/vectors/index.js @@ -893,6 +893,13 @@ async function onVectorizeAllFilesClick() { for (const file of allFiles) { const text = await getFileAttachment(file.url); const collectionId = getFileCollectionId(file.url); + const hashes = await getSavedHashes(collectionId); + + if (hashes.length) { + console.log(`Vectors: File ${file.name} is already vectorized`); + continue; + } + await vectorizeFile(text, file.name, collectionId, settings.chunk_size); } From c05404f8d5de4d78c6196862ee4affe4e39a1b5a Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sat, 20 Apr 2024 03:08:16 +0900 Subject: [PATCH 14/24] add Llama 3 context preset --- default/content/presets/context/Llama 3 Context.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 default/content/presets/context/Llama 3 Context.json diff --git a/default/content/presets/context/Llama 3 Context.json b/default/content/presets/context/Llama 3 Context.json new file mode 100644 index 000000000..c5af17def --- /dev/null +++ b/default/content/presets/context/Llama 3 Context.json @@ -0,0 +1,12 @@ +{ + "story_string": "<|begin_of_text|><|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{personality}}\n{{/if}}{{#if scenario}}{{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}<|eot_id|>", + "example_separator": "", + "chat_start": "", + "use_stop_strings": false, + "allow_jailbreak": false, + "always_force_name2": false, + "trim_sentences": true, + "include_newline": true, + "single_line": false, + "name": "Llama 3 Context" +} \ No newline at end of file From 1c5e7483e2cc09d29dfd473c9bb60ebee71f02df Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Sat, 20 Apr 2024 03:08:54 +0900 Subject: [PATCH 15/24] add Llama 3 instruct preset --- default/content/presets/instruct/Llama 3.json | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 default/content/presets/instruct/Llama 3.json diff --git a/default/content/presets/instruct/Llama 3.json b/default/content/presets/instruct/Llama 3.json new file mode 100644 index 000000000..1fd085ab5 --- /dev/null +++ b/default/content/presets/instruct/Llama 3.json @@ -0,0 +1,24 @@ +{ + "wrap": false, + "names": true, + "system_prompt": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}.", + "system_sequence": "<|start_header_id|>user({{name}})<|end_header_id|>\n\n", + "stop_sequence": "<|eot_id|>", + "input_sequence": "<|start_header_id|>user({{user}})<|end_header_id|>\n\n", + "output_sequence": "<|start_header_id|>assistant({{char}})<|end_header_id|>\n\n", + "macro": true, + "names_force_groups": false, + "last_output_sequence": "", + "activation_regex": "", + "system_sequence_prefix": "", + "system_sequence_suffix": "", + "first_output_sequence": "", + "skip_examples": false, + "output_suffix": "<|eot_id|>", + "input_suffix": "<|eot_id|>", + "system_suffix": "<|eot_id|>", + "user_alignment_message": "", + "system_same_as_user": false, + "last_system_sequence": "", + "name": "Llama 3" +} \ No newline at end of file From 391c3e9eff4584d47ef21aad83be93bec2d89801 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 22:08:31 +0300 Subject: [PATCH 16/24] Remove dupes, change system prompt --- .../presets/context/Llama 3 Context.json | 12 ---------- .../presets/instruct/Llama 3 Instruct.json | 4 ++-- default/content/presets/instruct/Llama 3.json | 24 ------------------- 3 files changed, 2 insertions(+), 38 deletions(-) delete mode 100644 default/content/presets/context/Llama 3 Context.json delete mode 100644 default/content/presets/instruct/Llama 3.json diff --git a/default/content/presets/context/Llama 3 Context.json b/default/content/presets/context/Llama 3 Context.json deleted file mode 100644 index c5af17def..000000000 --- a/default/content/presets/context/Llama 3 Context.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "story_string": "<|begin_of_text|><|start_header_id|>system<|end_header_id|>\n\n{{#if system}}{{system}}\n{{/if}}{{#if wiBefore}}{{wiBefore}}\n{{/if}}{{#if description}}{{description}}\n{{/if}}{{#if personality}}{{personality}}\n{{/if}}{{#if scenario}}{{scenario}}\n{{/if}}{{#if wiAfter}}{{wiAfter}}\n{{/if}}{{#if persona}}{{persona}}\n{{/if}}{{trim}}<|eot_id|>", - "example_separator": "", - "chat_start": "", - "use_stop_strings": false, - "allow_jailbreak": false, - "always_force_name2": false, - "trim_sentences": true, - "include_newline": true, - "single_line": false, - "name": "Llama 3 Context" -} \ No newline at end of file diff --git a/default/content/presets/instruct/Llama 3 Instruct.json b/default/content/presets/instruct/Llama 3 Instruct.json index 786540fec..111501287 100644 --- a/default/content/presets/instruct/Llama 3 Instruct.json +++ b/default/content/presets/instruct/Llama 3 Instruct.json @@ -1,5 +1,5 @@ { - "system_prompt": "Write {{char}}'s next reply in this fictional roleplay with {{user}}.", + "system_prompt": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}.", "input_sequence": "<|start_header_id|>user<|end_header_id|>\n\n", "output_sequence": "<|start_header_id|>assistant<|end_header_id|>\n\n", "last_output_sequence": "", @@ -21,4 +21,4 @@ "system_same_as_user": false, "last_system_sequence": "", "name": "Llama 3 Instruct" -} \ No newline at end of file +} diff --git a/default/content/presets/instruct/Llama 3.json b/default/content/presets/instruct/Llama 3.json deleted file mode 100644 index 1fd085ab5..000000000 --- a/default/content/presets/instruct/Llama 3.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "wrap": false, - "names": true, - "system_prompt": "You are an expert actor that can fully immerse yourself into any role given. You do not break character for any reason, even if someone tries addressing you as an AI or language model. Currently your role is {{char}}, which is described in detail below. As {{char}}, continue the exchange with {{user}}.", - "system_sequence": "<|start_header_id|>user({{name}})<|end_header_id|>\n\n", - "stop_sequence": "<|eot_id|>", - "input_sequence": "<|start_header_id|>user({{user}})<|end_header_id|>\n\n", - "output_sequence": "<|start_header_id|>assistant({{char}})<|end_header_id|>\n\n", - "macro": true, - "names_force_groups": false, - "last_output_sequence": "", - "activation_regex": "", - "system_sequence_prefix": "", - "system_sequence_suffix": "", - "first_output_sequence": "", - "skip_examples": false, - "output_suffix": "<|eot_id|>", - "input_suffix": "<|eot_id|>", - "system_suffix": "<|eot_id|>", - "user_alignment_message": "", - "system_same_as_user": false, - "last_system_sequence": "", - "name": "Llama 3" -} \ No newline at end of file From 0b6bb599557ddcb19f4ce5d0f59cbe090166abb9 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 22:46:49 +0300 Subject: [PATCH 17/24] Try optimize slash autocomplete --- public/scripts/slash-commands.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 272b0734a..215295e37 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -47,7 +47,7 @@ import { autoSelectPersona } from './personas.js'; import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js'; import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; import { decodeTextTokens, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync } from './tokenizers.js'; -import { delay, isFalseBoolean, isTrueBoolean, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; +import { debounce, delay, isFalseBoolean, isTrueBoolean, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js'; import { registerVariableCommands, resolveVariable } from './variables.js'; import { background_settings } from './backgrounds.js'; @@ -1863,11 +1863,24 @@ export async function executeSlashCommands(text, unescape = false) { return { interrupt, newText, pipe: pipeResult }; } +/** + * @param {JQuery} textarea + */ function setSlashCommandAutocomplete(textarea) { + const nativeElement = textarea.get(0); + let width = 0; + + function setItemWidth() { + width = nativeElement.offsetWidth - 5; + } + + const setWidthDebounced = debounce(setItemWidth); + $(window).on('resize', () => setWidthDebounced()); + textarea.autocomplete({ source: (input, output) => { // Only show for slash commands (requiring at least 1 letter after the slash) and if there's no space - if (!input.term.startsWith('/') || input.term.includes(' ') || input.term === '/') { + if (!input.term.startsWith('/') || input.term.includes(' ')) { output([]); return; } @@ -1877,7 +1890,7 @@ function setSlashCommandAutocomplete(textarea) { .keys(parser.helpStrings) // Get all slash commands .filter(x => x.startsWith(slashCommand)) // Filter by the input .sort((a, b) => a.localeCompare(b)) // Sort alphabetically - .slice(0, 5) // Limit to 5 results + .slice(0, 50) // Limit to 50 results .map(x => ({ label: parser.helpStrings[x], value: `/${x} ` })); // Map to the help string output(result); // Return the results @@ -1891,10 +1904,11 @@ function setSlashCommandAutocomplete(textarea) { }); textarea.autocomplete('instance')._renderItem = function (ul, item) { - const width = $(textarea).innerWidth(); const content = $('
').html(item.label); return $('
  • ').width(width).append(content).appendTo(ul); }; + + setItemWidth(); } jQuery(function () { From 366e2abb8ba4ef38a01fea6de0a267de21dc6feb Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 19 Apr 2024 23:01:31 +0300 Subject: [PATCH 18/24] Move expressions LLM request setting mode listener --- public/scripts/extensions/expressions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/extensions/expressions/index.js b/public/scripts/extensions/expressions/index.js index 2a1dff36e..9c763e550 100644 --- a/public/scripts/extensions/expressions/index.js +++ b/public/scripts/extensions/expressions/index.js @@ -1076,6 +1076,7 @@ async function getExpressionLabel(text) { case EXPRESSION_API.llm: { const expressionsList = await getExpressionsList(); const prompt = await getLlmPrompt(expressionsList); + eventSource.once(event_types.TEXT_COMPLETION_SETTINGS_READY, onTextGenSettingsReady); const emotionResponse = await generateQuietPrompt(prompt, false, false); return parseLlmResponse(emotionResponse, expressionsList); } @@ -1956,7 +1957,6 @@ function migrateSettings() { }); 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'], '(spriteId) – force sets the sprite for the current character', true, true); registerSlashCommand('spriteoverride', setSpriteSetCommand, ['costume'], '(optional folder) – 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()] ?? '', [], '(charName) – Returns the last set sprite / expression for the named character.', true, true); From 2a2a63c52c3bef1e27f20e98df698824b6bca462 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 20 Apr 2024 00:09:38 +0300 Subject: [PATCH 19/24] Add Perplexity as Chat Completion source --- public/img/perplexity.svg | 3 + public/index.html | 38 ++++++++++-- public/script.js | 7 ++- public/scripts/RossAscends-mods.js | 1 + public/scripts/openai.js | 69 +++++++++++++++++++++- public/scripts/secrets.js | 2 + public/scripts/slash-commands.js | 1 + public/scripts/tokenizers.js | 9 +++ src/constants.js | 1 + src/endpoints/backends/chat-completions.js | 9 ++- src/endpoints/secrets.js | 1 + 11 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 public/img/perplexity.svg diff --git a/public/img/perplexity.svg b/public/img/perplexity.svg new file mode 100644 index 000000000..1c10790e3 --- /dev/null +++ b/public/img/perplexity.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/index.html b/public/index.html index 73136c6d8..ccd952fc7 100644 --- a/public/index.html +++ b/public/index.html @@ -470,7 +470,7 @@
  • -
    +
    Temperature
    @@ -483,7 +483,7 @@
    -
    +
    Frequency Penalty
    @@ -496,7 +496,7 @@
    -
    +
    Presence Penalty
    @@ -522,7 +522,7 @@
    -
    +
    Top K
    @@ -535,7 +535,7 @@
    -
    +
    Top P
    @@ -2306,6 +2306,7 @@ + @@ -2704,6 +2705,33 @@
    +
    +

    Perplexity API Key

    +
    + + +
    +
    + For privacy reasons, your API key will be hidden after you reload the page. +
    +

    Perplexity Model

    + +

    Cohere API Key

    diff --git a/public/script.js b/public/script.js index 13be91c6f..1d7318e7b 100644 --- a/public/script.js +++ b/public/script.js @@ -8243,10 +8243,15 @@ const CONNECT_API_MAP = { source: chat_completion_sources.CUSTOM, }, 'cohere': { - selected: 'cohere', + selected: 'openai', button: '#api_button_openai', source: chat_completion_sources.COHERE, }, + 'perplexity': { + selected: 'openai', + button: '#api_button_openai', + source: chat_completion_sources.PERPLEXITY, + }, 'infermaticai': { selected: 'textgenerationwebui', button: '#api_button_textgenerationwebui', diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js index 57c135fb5..7c371b00f 100644 --- a/public/scripts/RossAscends-mods.js +++ b/public/scripts/RossAscends-mods.js @@ -376,6 +376,7 @@ function RA_autoconnect(PrevApi) { || (secret_state[SECRET_KEYS.MAKERSUITE] && oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) || (secret_state[SECRET_KEYS.MISTRALAI] && oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI) || (secret_state[SECRET_KEYS.COHERE] && oai_settings.chat_completion_source == chat_completion_sources.COHERE) + || (secret_state[SECRET_KEYS.PERPLEXITY] && oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) || (isValidUrl(oai_settings.custom_url) && oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) ) { $('#api_button_openai').trigger('click'); diff --git a/public/scripts/openai.js b/public/scripts/openai.js index 41c9b24a9..bc9ccc060 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -172,6 +172,7 @@ export const chat_completion_sources = { MISTRALAI: 'mistralai', CUSTOM: 'custom', COHERE: 'cohere', + PERPLEXITY: 'perplexity', }; const character_names_behavior = { @@ -238,6 +239,7 @@ const default_settings = { ai21_model: 'j2-ultra', mistralai_model: 'mistral-medium-latest', cohere_model: 'command-r', + perplexity_model: 'llama-3-70b-instruct', custom_model: '', custom_url: '', custom_include_body: '', @@ -310,6 +312,7 @@ const oai_settings = { ai21_model: 'j2-ultra', mistralai_model: 'mistral-medium-latest', cohere_model: 'command-r', + perplexity_model: 'llama-3-70b-instruct', custom_model: '', custom_url: '', custom_include_body: '', @@ -1410,6 +1413,8 @@ function getChatCompletionModel() { return oai_settings.custom_model; case chat_completion_sources.COHERE: return oai_settings.cohere_model; + case chat_completion_sources.PERPLEXITY: + return oai_settings.perplexity_model; default: throw new Error(`Unknown chat completion source: ${oai_settings.chat_completion_source}`); } @@ -1630,6 +1635,7 @@ async function sendOpenAIRequest(type, messages, signal) { const isMistral = oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI; const isCustom = oai_settings.chat_completion_source == chat_completion_sources.CUSTOM; const isCohere = oai_settings.chat_completion_source == chat_completion_sources.COHERE; + const isPerplexity = oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY; const isTextCompletion = (isOAI && textCompletionModels.includes(oai_settings.openai_model)) || (isOpenRouter && oai_settings.openrouter_force_instruct && power_user.instruct.enabled); const isQuiet = type === 'quiet'; const isImpersonate = type === 'impersonate'; @@ -1777,6 +1783,16 @@ async function sendOpenAIRequest(type, messages, signal) { generate_data['websearch'] = oai_settings.websearch_cohere; } + if (isPerplexity) { + generate_data['top_k'] = Number(oai_settings.top_k_openai); + // Normalize values. 1 == disabled. 0 == is usual disabled state in OpenAI. + generate_data['frequency_penalty'] = Math.max(0, Number(oai_settings.freq_pen_openai)) + 1; + generate_data['presence_penalty'] = Number(oai_settings.pres_pen_openai); + + // YEAH BRO JUST USE OPENAI CLIENT BRO + delete generate_data['stop']; + } + if ((isOAI || isOpenRouter || isMistral || isCustom || isCohere) && oai_settings.seed >= 0) { generate_data['seed'] = oai_settings.seed; } @@ -1847,7 +1863,7 @@ function getStreamingReply(data) { } else if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { return data?.candidates?.[0]?.content?.parts?.[0]?.text || ''; } else { - return data.choices[0]?.delta?.content || data.choices[0]?.message?.content || data.choices[0]?.text || ''; + return data.choices[0]?.delta?.content ?? data.choices[0]?.message?.content ?? data.choices[0]?.text ?? ''; } } @@ -2643,6 +2659,7 @@ function loadOpenAISettings(data, settings) { oai_settings.ai21_model = settings.ai21_model ?? default_settings.ai21_model; oai_settings.mistralai_model = settings.mistralai_model ?? default_settings.mistralai_model; oai_settings.cohere_model = settings.cohere_model ?? default_settings.cohere_model; + oai_settings.perplexity_model = settings.perplexity_model ?? default_settings.perplexity_model; oai_settings.custom_model = settings.custom_model ?? default_settings.custom_model; oai_settings.custom_url = settings.custom_url ?? default_settings.custom_url; oai_settings.custom_include_body = settings.custom_include_body ?? default_settings.custom_include_body; @@ -2708,6 +2725,8 @@ function loadOpenAISettings(data, settings) { $(`#model_mistralai_select option[value="${oai_settings.mistralai_model}"`).attr('selected', true); $('#model_cohere_select').val(oai_settings.cohere_model); $(`#model_cohere_select option[value="${oai_settings.cohere_model}"`).attr('selected', true); + $('#model_perplexity_select').val(oai_settings.perplexity_model); + $(`#model_perplexity_select option[value="${oai_settings.perplexity_model}"`).attr('selected', true); $('#custom_model_id').val(oai_settings.custom_model); $('#custom_api_url_text').val(oai_settings.custom_url); $('#openai_max_context').val(oai_settings.openai_max_context); @@ -2857,7 +2876,7 @@ async function getStatusOpen() { return resultCheckStatus(); } - const noValidateSources = [chat_completion_sources.SCALE, chat_completion_sources.CLAUDE, chat_completion_sources.AI21, chat_completion_sources.MAKERSUITE]; + const noValidateSources = [chat_completion_sources.SCALE, chat_completion_sources.CLAUDE, chat_completion_sources.AI21, chat_completion_sources.MAKERSUITE, chat_completion_sources.PERPLEXITY]; if (noValidateSources.includes(oai_settings.chat_completion_source)) { let status = 'Unable to verify key; press "Test Message" to validate.'; setOnlineStatus(status); @@ -2948,6 +2967,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { ai21_model: settings.ai21_model, mistralai_model: settings.mistralai_model, cohere_model: settings.cohere_model, + perplexity_model: settings.perplexity_model, custom_model: settings.custom_model, custom_url: settings.custom_url, custom_include_body: settings.custom_include_body, @@ -3340,6 +3360,7 @@ function onSettingsPresetChange() { ai21_model: ['#model_ai21_select', 'ai21_model', false], mistralai_model: ['#model_mistralai_select', 'mistralai_model', false], cohere_model: ['#model_cohere_select', 'cohere_model', false], + perplexity_model: ['#model_perplexity_select', 'perplexity_model', false], custom_model: ['#custom_model_id', 'custom_model', false], custom_url: ['#custom_api_url_text', 'custom_url', false], custom_include_body: ['#custom_include_body', 'custom_include_body', false], @@ -3563,6 +3584,11 @@ async function onModelChange() { oai_settings.cohere_model = value; } + if ($(this).is('#model_perplexity_select')) { + console.log('Perplexity model changed to', value); + oai_settings.perplexity_model = value; + } + if (value && $(this).is('#model_custom_select')) { console.log('Custom model changed to', value); oai_settings.custom_model = value; @@ -3706,6 +3732,28 @@ async function onModelChange() { $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); } + if (oai_settings.chat_completion_source === chat_completion_sources.PERPLEXITY) { + if (oai_settings.max_context_unlocked) { + $('#openai_max_context').attr('max', unlocked_max); + } + else if (['sonar-small-chat', 'sonar-medium-chat', 'codellama-70b-instruct', 'mistral-7b-instruct', 'mixtral-8x7b-instruct', 'mixtral-8x22b-instruct'].includes(oai_settings.perplexity_model)) { + $('#openai_max_context').attr('max', max_16k); + } + else if (['llama-3-8b-instruct', 'llama-3-70b-instruct'].includes(oai_settings.perplexity_model)) { + $('#openai_max_context').attr('max', max_8k); + } + else if (['sonar-small-online', 'sonar-medium-online'].includes(oai_settings.perplexity_model)) { + $('#openai_max_context').attr('max', 12000); + } + else { + $('#openai_max_context').attr('max', max_4k); + } + oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context); + $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); + oai_settings.temp_openai = Math.min(oai_max_temp, oai_settings.temp_openai); + $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); + } + if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { if (oai_settings.max_context_unlocked) { $('#openai_max_context').attr('max', unlocked_max); @@ -3912,6 +3960,19 @@ async function onConnectButtonClick(e) { } } + if (oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) { + const api_key_perplexity = String($('#api_key_perplexity').val()).trim(); + + if (api_key_perplexity.length) { + await writeSecret(SECRET_KEYS.PERPLEXITY, api_key_perplexity); + } + + if (!secret_state[SECRET_KEYS.PERPLEXITY]) { + console.log('No secret key saved for Perplexity'); + return; + } + } + startStatusLoading(); saveSettingsDebounced(); await getStatusOpen(); @@ -3950,6 +4011,9 @@ function toggleChatCompletionForms() { else if (oai_settings.chat_completion_source == chat_completion_sources.COHERE) { $('#model_cohere_select').trigger('change'); } + else if (oai_settings.chat_completion_source == chat_completion_sources.PERPLEXITY) { + $('#model_perplexity_select').trigger('change'); + } else if (oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) { $('#model_custom_select').trigger('change'); } @@ -4619,6 +4683,7 @@ $(document).ready(async function () { $('#model_ai21_select').on('change', onModelChange); $('#model_mistralai_select').on('change', onModelChange); $('#model_cohere_select').on('change', onModelChange); + $('#model_perplexity_select').on('change', onModelChange); $('#model_custom_select').on('change', onModelChange); $('#settings_preset_openai').on('change', onSettingsPresetChange); $('#new_oai_preset').on('click', onNewPresetClick); diff --git a/public/scripts/secrets.js b/public/scripts/secrets.js index a6bed1057..f6ebd1f2a 100644 --- a/public/scripts/secrets.js +++ b/public/scripts/secrets.js @@ -24,6 +24,7 @@ export const SECRET_KEYS = { KOBOLDCPP: 'api_key_koboldcpp', LLAMACPP: 'api_key_llamacpp', COHERE: 'api_key_cohere', + PERPLEXITY: 'api_key_perplexity', }; const INPUT_MAP = { @@ -49,6 +50,7 @@ const INPUT_MAP = { [SECRET_KEYS.KOBOLDCPP]: '#api_key_koboldcpp', [SECRET_KEYS.LLAMACPP]: '#api_key_llamacpp', [SECRET_KEYS.COHERE]: '#api_key_cohere', + [SECRET_KEYS.PERPLEXITY]: '#api_key_perplexity', }; async function clearSecret() { diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 215295e37..f02c086c6 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -1682,6 +1682,7 @@ function modelCallback(_, model) { { id: 'model_mistralai_select', api: 'openai', type: chat_completion_sources.MISTRALAI }, { id: 'model_custom_select', api: 'openai', type: chat_completion_sources.CUSTOM }, { id: 'model_cohere_select', api: 'openai', type: chat_completion_sources.COHERE }, + { id: 'model_perplexity_select', api: 'openai', type: chat_completion_sources.PERPLEXITY }, { id: 'model_novel_select', api: 'novel', type: null }, { id: 'horde_model', api: 'koboldhorde', type: null }, ]; diff --git a/public/scripts/tokenizers.js b/public/scripts/tokenizers.js index 7e9fc7856..3c44fdd1d 100644 --- a/public/scripts/tokenizers.js +++ b/public/scripts/tokenizers.js @@ -497,6 +497,15 @@ export function getTokenizerModel() { return oai_settings.custom_model; } + if (oai_settings.chat_completion_source === chat_completion_sources.PERPLEXITY) { + if (oai_settings.perplexity_model.includes('llama')) { + return llamaTokenizer; + } + if (oai_settings.perplexity_model.includes('mistral')) { + return mistralTokenizer; + } + } + // Default to Turbo 3.5 return turboTokenizer; } diff --git a/src/constants.js b/src/constants.js index e7831bf48..d733f2b33 100644 --- a/src/constants.js +++ b/src/constants.js @@ -163,6 +163,7 @@ const CHAT_COMPLETION_SOURCES = { MISTRALAI: 'mistralai', CUSTOM: 'custom', COHERE: 'cohere', + PERPLEXITY: 'perplexity', }; const UPLOADS_PATH = './uploads'; diff --git a/src/endpoints/backends/chat-completions.js b/src/endpoints/backends/chat-completions.js index 494282a5b..015457726 100644 --- a/src/endpoints/backends/chat-completions.js +++ b/src/endpoints/backends/chat-completions.js @@ -14,6 +14,7 @@ const API_OPENAI = 'https://api.openai.com/v1'; const API_CLAUDE = 'https://api.anthropic.com/v1'; const API_MISTRAL = 'https://api.mistral.ai/v1'; const API_COHERE = 'https://api.cohere.ai/v1'; +const API_PERPLEXITY = 'https://api.perplexity.ai'; /** * Applies a post-processing step to the generated messages. @@ -439,7 +440,7 @@ async function sendAI21Request(request, response) { } else { console.log(r.completions[0].data.text); } - const reply = { choices: [{ 'message': { 'content': r.completions[0].data.text } }] }; + const reply = { choices: [{ 'message': { 'content': r.completions?.[0]?.data?.text } }] }; return response.send(reply); }) .catch(err => { @@ -894,6 +895,12 @@ router.post('/generate', jsonParser, function (request, response) { request.body.char_name, request.body.user_name); } + } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.PERPLEXITY) { + apiUrl = API_PERPLEXITY; + apiKey = readSecret(SECRET_KEYS.PERPLEXITY); + headers = {}; + bodyParams = {}; + request.body.messages = postProcessPrompt(request.body.messages, 'claude', request.body.char_name, request.body.user_name); } else { console.log('This chat completion source is not supported yet.'); return response.status(400).send({ error: true }); diff --git a/src/endpoints/secrets.js b/src/endpoints/secrets.js index afd41a1f7..79e8cda8f 100644 --- a/src/endpoints/secrets.js +++ b/src/endpoints/secrets.js @@ -36,6 +36,7 @@ const SECRET_KEYS = { KOBOLDCPP: 'api_key_koboldcpp', LLAMACPP: 'api_key_llamacpp', COHERE: 'api_key_cohere', + PERPLEXITY: 'api_key_perplexity', }; // These are the keys that are safe to expose, even if allowKeysExposure is false From 3ff5884112044d01da4e7f145685eaab38cb05fd Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 20 Apr 2024 01:11:37 +0300 Subject: [PATCH 20/24] Forbid external media by default --- default/content/settings.json | 3 ++- public/index.html | 4 ++-- public/scripts/chats.js | 8 ++++---- public/scripts/power-user.js | 8 ++++---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/default/content/settings.json b/default/content/settings.json index ef7f4f0b1..aef108eac 100644 --- a/default/content/settings.json +++ b/default/content/settings.json @@ -194,7 +194,8 @@ "encode_tags": false, "enableLabMode": false, "enableZenSliders": false, - "ui_mode": 1 + "ui_mode": 1, + "forbid_external_media": true }, "extension_settings": { "apiUrl": "http://localhost:5100", diff --git a/public/index.html b/public/index.html index 910f36688..f1cff600b 100644 --- a/public/index.html +++ b/public/index.html @@ -3944,8 +3944,8 @@ -