(
messages: BaseMessageLike[],
options: ICommonObject
)
| 94 | * use `revertBase64ImagesToFileRefs` to restore lightweight file references. |
| 95 | */ |
| 96 | export const processMessagesWithImages = async ( |
| 97 | messages: BaseMessageLike[], |
| 98 | options: ICommonObject |
| 99 | ): Promise<{ |
| 100 | updatedMessages: BaseMessageLike[] |
| 101 | transformedMessages: BaseMessageLike[] |
| 102 | }> => { |
| 103 | if (!messages || !options.chatflowid || !options.chatId) { |
| 104 | return { |
| 105 | updatedMessages: messages, |
| 106 | transformedMessages: [] |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // Create a deep copy of the messages to avoid mutating the original |
| 111 | const updatedMessages: IChatMessage[] = JSON.parse(JSON.stringify(messages)) |
| 112 | // Track which messages were transformed |
| 113 | const transformedMessages: BaseMessageLike[] = [] |
| 114 | |
| 115 | // Scan through all messages looking for stored-file references |
| 116 | for (let i = 0; i < updatedMessages.length; i++) { |
| 117 | const message = updatedMessages[i] |
| 118 | // Skip non-user messages or messages without content |
| 119 | if (message.role !== 'user' || !Array.isArray(message.content)) continue |
| 120 | |
| 121 | const imageContents: MessageContentImageUrl[] = [] |
| 122 | const fileRefs: IImageFileRef[] = [] |
| 123 | let hasImageReferences = false |
| 124 | |
| 125 | // Find stored-file image items and convert them to base64 image_url items |
| 126 | for (const item of message.content as IMultimodalContentItem[]) { |
| 127 | if (item.type === 'stored-file' && item.name && item.mime?.startsWith('image/')) { |
| 128 | hasImageReferences = true |
| 129 | try { |
| 130 | const fileName = sanitizeFileName(item.name) |
| 131 | const base64Url = await storedFileToBase64(fileName, item.mime, options) |
| 132 | // Track which content index maps to which file, so we can revert later |
| 133 | fileRefs.push({ index: imageContents.length, fileName, mime: item.mime }) |
| 134 | imageContents.push({ |
| 135 | type: 'image_url', |
| 136 | image_url: { |
| 137 | url: base64Url |
| 138 | } |
| 139 | }) |
| 140 | } catch (error) { |
| 141 | console.error(`Failed to load image ${item.name}:`, error) |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | if (imageContents.length > 0) { |
| 147 | // Save a copy of the original message before we replace its content |
| 148 | if (hasImageReferences) { |
| 149 | transformedMessages.push(JSON.parse(JSON.stringify(messages[i]))) |
| 150 | } |
| 151 | updatedMessages[i].content = imageContents |
| 152 | // Store file refs in additional_kwargs (not sent to the LLM API) |
| 153 | if (fileRefs.length > 0) { |
no test coverage detected