Support images in custom prompt post-processing
| @@ -628,11 +628,30 @@ export function convertMistralMessages(messages, charName = '', userName = '') { | ||
| 628 | 628 | export function mergeMessages(messages, charName, userName, strict) { |
| 629 | 629 | let mergedMessages = []; |
| 630 | 630 | |
| 631 | + /** @type {Map<string,object>} */ | |
| 632 | + const contentTokens = new Map(); | |
| 633 | + | |
| 631 | 634 | // Remove names from the messages |
| 632 | 635 | messages.forEach((message) => { |
| 633 | 636 | if (!message.content) { |
| 634 | 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 | 655 | if (message.role === 'system' && message.name === 'example_assistant') { |
| 637 | 656 | if (charName && !message.content.startsWith(`${charName}: `)) { |
| 638 | 657 | message.content = `${charName}: ${message.content}`; |
| @@ -673,6 +692,32 @@ export function mergeMessages(messages, charName, userName, strict) { | ||
| 673 | 692 | }); |
| 674 | 693 | } |
| 675 | 694 | |
| 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 | 721 | if (strict) { |
| 677 | 722 | for (let i = 0; i < mergedMessages.length; i++) { |
| 678 | 723 | // Force mid-prompt system messages to be user messages |