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