Fix xAI example messages conversion

5eeba8894e692410cd5bb788900eb5c422924228

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +39 -0Ignore whitespace
src/endpoints/backends/chat-completions.js+2 -0
@@ -23,6 +23,7 @@ import {
23 convertCohereMessages,23 convertCohereMessages,
24 convertMistralMessages,24 convertMistralMessages,
25 convertAI21Messages,25 convertAI21Messages,
26 convertXAIMessages,
26 mergeMessages,27 mergeMessages,
27 cachingAtDepthForOpenRouterClaude,28 cachingAtDepthForOpenRouterClaude,
28 cachingAtDepthForClaude,29 cachingAtDepthForClaude,
@@ -1159,6 +1160,7 @@ router.post('/generate', function (request, response) {
1159 apiKey = readSecret(request.user.directories, SECRET_KEYS.XAI);1160 apiKey = readSecret(request.user.directories, SECRET_KEYS.XAI);
1160 headers = {};1161 headers = {};
1161 bodyParams = {};1162 bodyParams = {};
1163 request.body.messages = convertXAIMessages(request.body.messages, getPromptNames(request));
1162 } else {1164 } else {
1163 console.warn('This chat completion source is not supported yet.');1165 console.warn('This chat completion source is not supported yet.');
1164 return response.status(400).send({ error: true });1166 return response.status(400).send({ error: true });
src/prompt-converters.js+37 -0
@@ -680,6 +680,43 @@ export function convertMistralMessages(messages, names) {
680}680}
681681
682/**682/**
683 * Convert a prompt from the messages objects to the format used by xAI.
684 * @param {object[]} messages Array of messages
685 * @param {PromptNames} names Prompt names
686 * @returns {object[]} Prompt for xAI
687 */
688export function convertXAIMessages(messages, names) {
689 if (!Array.isArray(messages)) {
690 return [];
691 }
692
693 messages.forEach(msg => {
694 if (!msg.name || msg.role === 'user') {
695 return;
696 }
697
698 const needsCharNamePrefix = [
699 { role: 'assistant', condition: names.charName && !msg.content.startsWith(`${names.charName}: `) && !names.startsWithGroupName(msg.content) },
700 { role: 'system', name: 'example_assistant', condition: names.charName && !msg.content.startsWith(`${names.charName}: `) && !names.startsWithGroupName(msg.content) },
701 { role: 'system', name: 'example_user', condition: names.userName && !msg.content.startsWith(`${names.userName}: `) },
702 ];
703
704 const matchingRule = needsCharNamePrefix.find(rule =>
705 msg.role === rule.role && (!rule.name || msg.name === rule.name) && rule.condition,
706 );
707
708 if (matchingRule) {
709 const prefix = msg.role === 'system' && msg.name === 'example_user' ? names.userName : names.charName;
710 msg.content = `${prefix}: ${msg.content}`;
711 }
712
713 delete msg.name;
714 });
715
716 return messages;
717}
718
719/**
683 * Merge messages with the same consecutive role, removing names if they exist.720 * Merge messages with the same consecutive role, removing names if they exist.
684 * @param {any[]} messages Messages to merge721 * @param {any[]} messages Messages to merge
685 * @param {PromptNames} names Prompt names722 * @param {PromptNames} names Prompt names