SillyTavern/src/chat-completion.js

78 lines
2.4 KiB
JavaScript
Raw Normal View History

/**
* Convert a prompt from the ChatML objects to the format used by Claude.
* @param {object[]} messages Array of messages
* @param {boolean} addHumanPrefix Add Human prefix
* @param {boolean} addAssistantPostfix Add Assistant postfix
2023-11-21 21:11:26 +01:00
* @param {boolean} withSystemPrompt Build system prompt before "\n\nHuman: "
* @returns {string} Prompt for Claude
* @copyright Prompt Conversion script taken from RisuAI by kwaroran (GPLv3).
*/
2023-11-21 21:11:26 +01:00
function convertClaudePrompt(messages, addHumanPrefix, addAssistantPostfix, withSystemPrompt) {
// Claude doesn't support message names, so we'll just add them to the message content.
for (const message of messages) {
2023-12-02 19:04:51 +01:00
if (message.name && message.role !== 'system') {
message.content = message.name + ': ' + message.content;
delete message.name;
}
}
2023-11-21 21:11:26 +01:00
let systemPrompt = '';
if (withSystemPrompt) {
2023-11-24 21:58:20 +01:00
let lastSystemIdx = -1;
for (let i = 0; i < messages.length - 1; i++) {
const message = messages[i];
2023-12-02 19:04:51 +01:00
if (message.role === 'system' && !message.name) {
2023-11-21 21:11:26 +01:00
systemPrompt += message.content + '\n\n';
} else {
2023-11-24 21:58:20 +01:00
lastSystemIdx = i - 1;
2023-11-21 21:11:26 +01:00
break;
}
}
2023-11-24 21:58:20 +01:00
if (lastSystemIdx >= 0) {
messages.splice(0, lastSystemIdx + 1);
}
2023-11-21 21:11:26 +01:00
}
let requestPrompt = messages.map((v) => {
let prefix = '';
switch (v.role) {
2023-12-02 19:04:51 +01:00
case 'assistant':
prefix = '\n\nAssistant: ';
2023-12-02 20:11:06 +01:00
break;
2023-12-02 19:04:51 +01:00
case 'user':
prefix = '\n\nHuman: ';
2023-12-02 20:11:06 +01:00
break;
2023-12-02 19:04:51 +01:00
case 'system':
// According to the Claude docs, H: and A: should be used for example conversations.
2023-12-02 19:04:51 +01:00
if (v.name === 'example_assistant') {
prefix = '\n\nA: ';
} else if (v.name === 'example_user') {
prefix = '\n\nH: ';
} else {
2023-12-02 19:04:51 +01:00
prefix = '\n\n';
}
2023-12-02 20:11:06 +01:00
break;
}
return prefix + v.content;
}).join('');
if (addHumanPrefix) {
2023-12-02 19:04:51 +01:00
requestPrompt = '\n\nHuman: ' + requestPrompt;
}
if (addAssistantPostfix) {
requestPrompt = requestPrompt + '\n\nAssistant: ';
}
2023-11-21 21:11:26 +01:00
if (withSystemPrompt) {
requestPrompt = systemPrompt + requestPrompt;
}
return requestPrompt;
}
module.exports = {
convertClaudePrompt,
2023-12-02 20:11:06 +01:00
};