Support images in custom prompt post-processing

6ae120900ddabe7accf2313d1c8e52a1a86cf18f

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

1 files changed, +45 -0Ignore whitespace
src/prompt-converters.js+45 -0
@@ -628,11 +628,30 @@ export function convertMistralMessages(messages, charName = '', userName = '') {
628export function mergeMessages(messages, charName, userName, strict) {628export function mergeMessages(messages, charName, userName, strict) {
629 let mergedMessages = [];629 let mergedMessages = [];
630630
631 /** @type {Map<string,object>} */
632 const contentTokens = new Map();
633
631 // Remove names from the messages634 // Remove names from the messages
632 messages.forEach((message) => {635 messages.forEach((message) => {
633 if (!message.content) {636 if (!message.content) {
634 message.content = '';637 message.content = '';
635 }638 }
639 // Flatten contents and replace image URLs with random tokens
640 if (Array.isArray(message.content)) {
641 const text = message.content.map((content) => {
642 if (content.type === 'text') {
643 return content.text;
644 }
645 // Could be extended with other non-text types
646 if (content.type === 'image_url') {
647 const token = crypto.randomBytes(32).toString('base64');
648 contentTokens.set(token, content);
649 return token;
650 }
651 return '';
652 }).join('\n\n');
653 message.content = text;
654 }
636 if (message.role === 'system' && message.name === 'example_assistant') {655 if (message.role === 'system' && message.name === 'example_assistant') {
637 if (charName && !message.content.startsWith(`${charName}: `)) {656 if (charName && !message.content.startsWith(`${charName}: `)) {
638 message.content = `${charName}: ${message.content}`;657 message.content = `${charName}: ${message.content}`;
@@ -673,6 +692,32 @@ export function mergeMessages(messages, charName, userName, strict) {
673 });692 });
674 }693 }
675694
695 // Check for content tokens and replace them with the actual content objects
696 if (contentTokens.size > 0) {
697 mergedMessages.forEach((message) => {
698 const hasValidToken = Array.from(contentTokens.keys()).some(token => message.content.includes(token));
699
700 if (hasValidToken) {
701 const splitContent = message.content.split('\n\n');
702 const mergedContent = [];
703
704 splitContent.forEach((content) => {
705 if (contentTokens.has(content)) {
706 mergedContent.push(contentTokens.get(content));
707 } else {
708 if (mergedContent.length > 0 && mergedContent[mergedContent.length - 1].type === 'text') {
709 mergedContent[mergedContent.length - 1].text += `\n\n${content}`;
710 } else {
711 mergedContent.push({ type: 'text', text: content });
712 }
713 }
714 });
715
716 message.content = mergedContent;
717 }
718 });
719 }
720
676 if (strict) {721 if (strict) {
677 for (let i = 0; i < mergedMessages.length; i++) {722 for (let i = 0; i < mergedMessages.length; i++) {
678 // Force mid-prompt system messages to be user messages723 // Force mid-prompt system messages to be user messages