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 {
2323 convertCohereMessages,
2424 convertMistralMessages,
2525 convertAI21Messages,
26+ convertXAIMessages,
2627 mergeMessages,
2728 cachingAtDepthForOpenRouterClaude,
2829 cachingAtDepthForClaude,
@@ -1159,6 +1160,7 @@ router.post('/generate', function (request, response) {
11591160 apiKey = readSecret(request.user.directories, SECRET_KEYS.XAI);
11601161 headers = {};
11611162 bodyParams = {};
1163+ request.body.messages = convertXAIMessages(request.body.messages, getPromptNames(request));
11621164 } else {
11631165 console.warn('This chat completion source is not supported yet.');
11641166 return response.status(400).send({ error: true });
src/prompt-converters.js+37 -0
@@ -680,6 +680,43 @@ export function convertMistralMessages(messages, names) {
680680}
681681
682682/**
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+ */
688+export 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+/**
683720 * Merge messages with the same consecutive role, removing names if they exist.
684721 * @param {any[]} messages Messages to merge
685722 * @param {PromptNames} names Prompt names