Merge branch 'staging' of https://github.com/DonMoralez/SillyTavern into staging
This commit is contained in:
commit
1456ebd4bb
|
@ -1537,29 +1537,38 @@
|
|||
</div>
|
||||
<div data-newbie-hidden class="range-block" data-source="claude">
|
||||
<label for="exclude_assistant" title="Exclude Assistant suffix" class="checkbox_label widthFreeExpand">
|
||||
<input id="exclude_assistant" type="checkbox" /><span data-i18n="Exclude Assistant suffix">Exclude Assistant suffix</span>
|
||||
<input id="exclude_assistant" type="checkbox" />
|
||||
<span data-i18n="Exclude Assistant suffix">Exclude Assistant suffix</span>
|
||||
</label>
|
||||
<div class="toggle-description justifyLeft">
|
||||
<span data-i18n="Exclude the assistant suffix from being added to the end of prompt.">Exclude the assistant suffix from being added to the end of prompt (Requires jailbreak with 'Assistant:' in it).</span>
|
||||
<span data-i18n="Exclude the assistant suffix from being added to the end of prompt.">
|
||||
Exclude the assistant suffix from being added to the end of prompt (Requires jailbreak with 'Assistant:' in it).
|
||||
</span>
|
||||
</div>
|
||||
<div id="claude_assistant_prefill_block" data-source="claude" class="wide100p">
|
||||
<div id="claude_assistant_prefill_block" class="wide100p">
|
||||
<span id="claude_assistant_prefill_text" data-i18n="Assistant Prefill">Assistant Prefill</span>
|
||||
<textarea id="claude_assistant_prefill" class="text_pole textarea_compact" name="assistant_prefill autoSetHeight" rows="3" maxlength="10000" data-i18n="[placeholder]Start Claude's answer with..." placeholder="Start Claude's answer with..."></textarea>
|
||||
</div>
|
||||
<label for="claude_use_sysprompt" title="Use system prompt(claude 2.1+ only)" class="checkbox_label widthFreeExpand">
|
||||
<input id="claude_use_sysprompt" type="checkbox" /><span data-i18n="Use system prompt(claude 2.1+ only)">Use system prompt(claude 2.1+ only)</span>
|
||||
<label for="claude_use_sysprompt" class="checkbox_label widthFreeExpand">
|
||||
<input id="claude_use_sysprompt" type="checkbox" />
|
||||
<span data-i18n="Use system prompt (Claude 2.1+ only)">
|
||||
Use system prompt (Claude 2.1+ only)
|
||||
</span>
|
||||
</label>
|
||||
<div class="toggle-description justifyLeft">
|
||||
<span data-i18n="Exclude the 'Human: ' prefix from being added to the beginning of the prompt.">Exclude the 'Human: ' prefix from being added to the beginning of the prompt. Instead, place it between the sysprompt and the first message with the role 'assistant'(right before 'Chat History', by default).</span>
|
||||
<span data-i18n="Exclude the 'Human: ' prefix from being added to the beginning of the prompt.">
|
||||
Exclude the 'Human: ' prefix from being added to the beginning of the prompt.
|
||||
Instead, place it between the system prompt and the first message with the role 'assistant' (right before 'Chat History' by default).
|
||||
</span>
|
||||
</div>
|
||||
<div id="claude_human_sysprompt_message_block" data-source="claude" class="wide100p">
|
||||
<div id="claude_human_sysprompt_message_block" class="wide100p">
|
||||
<div class="range-block-title openai_restorable">
|
||||
<span id="claude_human_sysprompt_textarea_text" data-i18n="Human: first message">Human: first message</span>
|
||||
<span data-i18n="Human: first message">Human: first message</span>
|
||||
<div id="claude_human_sysprompt_message_restore" title="Restore Human: first message" class="right_menu_button">
|
||||
<div class="fa-solid fa-clock-rotate-left"></div>
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="claude_human_sysprompt_textarea" class="text_pole textarea_compact" name="human_sysprompt_message autoSetHeight" rows="3" maxlength="10000" data-i18n="[placeholder]Your(Human: ) message, instruction, etc... !!WHEN EMPTY, ADDS NOTHING!!I.e., requires a new prompt with the role 'user' or manually adding the 'Human: ' prefix." placeholder="Your(Human: ) message, instruction, etc... !!WHEN EMPTY, ADDS NOTHING!! I.e., requires a new prompt with the role 'user' or manually adding the 'Human: ' prefix."></textarea>
|
||||
<textarea id="claude_human_sysprompt_textarea" class="text_pole textarea_compact" rows="4" maxlength="10000" data-i18n="[placeholder]Human message" placeholder="Human message, instruction, etc. Adds nothing when empty, i.e. requires a new prompt with the role 'user' or manually adding the 'Human: ' prefix."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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, {
|
||||
|
|
Loading…
Reference in New Issue