diff --git a/public/index.html b/public/index.html index a9009dee9..595c61791 100644 --- a/public/index.html +++ b/public/index.html @@ -1537,29 +1537,38 @@
- Exclude the assistant suffix from being added to the end of prompt (Requires jailbreak with 'Assistant:' in it). + + Exclude the assistant suffix from being added to the end of prompt (Requires jailbreak with 'Assistant:' in it). +
-
+
Assistant Prefill
-
diff --git a/src/endpoints/backends/chat-completions.js b/src/endpoints/backends/chat-completions.js index 436d7d9c3..42ec0c065 100644 --- a/src/endpoints/backends/chat-completions.js +++ b/src/endpoints/backends/chat-completions.js @@ -4,7 +4,7 @@ const { Readable } = require('stream'); const { jsonParser } = require('../../express-common'); const { CHAT_COMPLETION_SOURCES, GEMINI_SAFETY, BISON_SAFETY } = require('../../constants'); -const { forwardFetchResponse, getConfigValue, tryParse, uuidv4 } = require('../../util'); +const { forwardFetchResponse, getConfigValue, tryParse, uuidv4, color } = require('../../util'); const { convertClaudePrompt, convertGooglePrompt, convertTextCompletionPrompt } = require('../prompt-converters'); const { readSecret, SECRET_KEYS } = require('../secrets'); @@ -21,11 +21,10 @@ const API_CLAUDE = 'https://api.anthropic.com/v1'; async function sendClaudeRequest(request, response) { const apiUrl = new URL(request.body.reverse_proxy || API_CLAUDE).toString(); const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(SECRET_KEYS.CLAUDE); - const chalk = require('chalk'); const divider = '-'.repeat(process.stdout.columns); if (!apiKey) { - console.log(chalk.red(`Claude API key is missing.\n${divider}`)); + console.log(color.red(`Claude API key is missing.\n${divider}`)); return response.status(400).send({ error: true }); } @@ -36,17 +35,17 @@ async function sendClaudeRequest(request, response) { controller.abort(); }); - let isSyspromptSupported = request.body.model === 'claude-2' || request.body.model === 'claude-2.1'; - let requestPrompt = convertClaudePrompt(request.body.messages, !request.body.exclude_assistant, request.body.assistant_prefill, isSyspromptSupported, request.body.claude_use_sysprompt, request.body.human_sysprompt_message); + const isSysPromptSupported = request.body.model === 'claude-2' || request.body.model === 'claude-2.1'; + const requestPrompt = convertClaudePrompt(request.body.messages, !request.body.exclude_assistant, request.body.assistant_prefill, isSysPromptSupported, request.body.claude_use_sysprompt, request.body.human_sysprompt_message); - console.log(chalk.green(`${divider}\nClaude request\n`) + chalk.cyan(`PROMPT\n${divider}\n${requestPrompt}\n${divider}`)); + console.log(color.green(`${divider}\nClaude request\n`) + color.cyan(`PROMPT\n${divider}\n${requestPrompt}\n${divider}`)); // Check Claude messages sequence and prefixes presence. const sequence = requestPrompt.split('\n').filter(x => x.startsWith('Human:') || x.startsWith('Assistant:')); + const humanFound = sequence.some(line => line.startsWith('Human:')); + const assistantFound = sequence.some(line => line.startsWith('Assistant:')); let humanErrorCount = 0; let assistantErrorCount = 0; - let humanFound = sequence.some(line => line.startsWith('Human:')); - let assistantFound = sequence.some(line => line.startsWith('Assistant:')); for (let i = 0; i < sequence.length - 1; i++) { if (sequence[i].startsWith(sequence[i + 1].split(':')[0])) { @@ -59,20 +58,20 @@ async function sendClaudeRequest(request, response) { } if (!humanFound) { - console.log(chalk.red(`${divider}\nWarning: No 'Human:' prefix found in the prompt.\n${divider}`)); + console.log(color.red(`${divider}\nWarning: No 'Human:' prefix found in the prompt.\n${divider}`)); } if (!assistantFound) { - console.log(chalk.red(`${divider}\nWarning: No 'Assistant: ' prefix found in the prompt.\n${divider}`)); + console.log(color.red(`${divider}\nWarning: No 'Assistant: ' prefix found in the prompt.\n${divider}`)); } if (!sequence[0].startsWith('Human:')) { - console.log(chalk.red(`${divider}\nWarning: The messages sequence should start with 'Human:' prefix.\nMake sure you have 'Human:' prefix at the very beggining of the prompt, or after the system prompt.\n${divider}`)); + console.log(color.red(`${divider}\nWarning: The messages sequence should start with 'Human:' prefix.\nMake sure you have 'Human:' prefix at the very beggining of the prompt, or after the system prompt.\n${divider}`)); } if (humanErrorCount > 0 || assistantErrorCount > 0) { - console.log(chalk.red(`${divider}\nWarning: Detected incorrect Prefix sequence(s).`)); - console.log(chalk.red(`Incorrect "Human:" prefix(es): ${humanErrorCount}.\nIncorrect "Assistant: " prefix(es): ${assistantErrorCount}.`)); - console.log(chalk.red('Check the prompt above and fix it in the sillytavern.')); - console.log(chalk.red('\nThe correct sequence should look like this:\nSystem prompt <-(for the sysprompt format only, else have 2 empty lines above the first human\'s message.)')); - console.log(chalk.red(` <-----(Each message beginning with the "Assistant:/Human:" prefix must have one empty line above.)\nHuman:\n\nAssistant:\n...\n\nHuman:\n\nAssistant:\n${divider}`)); + console.log(color.red(`${divider}\nWarning: Detected incorrect Prefix sequence(s).`)); + console.log(color.red(`Incorrect "Human:" prefix(es): ${humanErrorCount}.\nIncorrect "Assistant: " prefix(es): ${assistantErrorCount}.`)); + console.log(color.red('Check the prompt above and fix it in the sillytavern.')); + console.log(color.red('\nThe correct sequence should look like this:\nSystem prompt <-(for the sysprompt format only, else have 2 empty lines above the first human\'s message.)')); + console.log(color.red(` <-----(Each message beginning with the "Assistant:/Human:" prefix must have one empty line above.)\nHuman:\n\nAssistant:\n...\n\nHuman:\n\nAssistant:\n${divider}`)); } const stop_sequences = ['\n\nHuman:', '\n\nSystem:', '\n\nAssistant:']; @@ -107,20 +106,20 @@ async function sendClaudeRequest(request, response) { forwardFetchResponse(generateResponse, response); } else { if (!generateResponse.ok) { - console.log(chalk.red(`Claude API returned error: ${generateResponse.status} ${generateResponse.statusText}\n${await generateResponse.text()}\n${divider}`)); + console.log(color.red(`Claude API returned error: ${generateResponse.status} ${generateResponse.statusText}\n${await generateResponse.text()}\n${divider}`)); return response.status(generateResponse.status).send({ error: true }); } const generateResponseJson = await generateResponse.json(); const responseText = generateResponseJson.completion; - console.log(chalk.green(`Claude response\n${divider}\n${responseText}\n${divider}`)); + console.log(color.green(`Claude response\n${divider}\n${responseText}\n${divider}`)); // Wrap it back to OAI format const reply = { choices: [{ 'message': { 'content': responseText } }] }; return response.send(reply); } } catch (error) { - console.log(chalk.red(`Error communicating with Claude: ${error}\n${divider}`)); + console.log(color.red(`Error communicating with Claude: ${error}\n${divider}`)); if (!response.headersSent) { return response.status(500).send({ error: true }); } diff --git a/src/endpoints/prompt-converters.js b/src/endpoints/prompt-converters.js index 3d864e1b8..12efd1cdc 100644 --- a/src/endpoints/prompt-converters.js +++ b/src/endpoints/prompt-converters.js @@ -3,13 +3,13 @@ * @param {object[]} messages Array of messages * @param {boolean} addAssistantPostfix Add Assistant postfix. * @param {string} addAssistantPrefill Add Assistant prefill after the assistant postfix. - * @param {boolean} withSyspromptSupport Indicates if the Claude model supports the system prompt format. + * @param {boolean} withSysPromptSupport Indicates if the Claude model supports the system prompt format. * @param {boolean} useSystemPrompt Indicates if the system prompt format should be used. * @param {string} addSysHumanMsg Add Human message between system prompt and assistant. * @returns {string} Prompt for Claude * @copyright Prompt Conversion script taken from RisuAI by kwaroran (GPLv3). */ -function convertClaudePrompt(messages, addAssistantPostfix, addAssistantPrefill, withSyspromptSupport, useSystemPrompt, addSysHumanMsg) { +function convertClaudePrompt(messages, addAssistantPostfix, addAssistantPrefill, withSysPromptSupport, useSystemPrompt, addSysHumanMsg) { //Prepare messages for claude. if (messages.length > 0) { @@ -31,7 +31,7 @@ function convertClaudePrompt(messages, addAssistantPostfix, addAssistantPrefill, }); // When 2.1+ and 'Use system prompt" checked, switches to the system prompt format by setting the first message's role to the 'system'. // Inserts the human's message before the first the assistant one, if there are no such message or prefix found. - if (withSyspromptSupport && useSystemPrompt) { + if (withSysPromptSupport && useSystemPrompt) { messages[0].role = 'system'; if (firstAssistantIndex > 0 && addSysHumanMsg && !hasUser) { messages.splice(firstAssistantIndex, 0, {