(
options: ICommonObject,
messages: BaseMessageLike[],
modelConfig?: ICommonObject
)
| 248 | * Returns undefined if no new unique images are found. |
| 249 | */ |
| 250 | export const getUniqueImageMessages = async ( |
| 251 | options: ICommonObject, |
| 252 | messages: BaseMessageLike[], |
| 253 | modelConfig?: ICommonObject |
| 254 | ): Promise<{ imageMessageWithFileRef: BaseMessageLike; imageMessageWithBase64: BaseMessageLike } | undefined> => { |
| 255 | if (!options.uploads) return undefined |
| 256 | |
| 257 | // Get images from uploads |
| 258 | const images = await _addImagesToMessages(options, modelConfig?.allowImageUploads ?? false) |
| 259 | const imageUploads = getImageUploads(options.uploads) |
| 260 | |
| 261 | // Collect (fileName, mime) already present in messages via _imageFileRefs |
| 262 | const alreadyPresentRefs = new Set<string>() |
| 263 | for (const msg of messages) { |
| 264 | const refs = (msg as IChatMessage).additional_kwargs?._imageFileRefs |
| 265 | if (refs) { |
| 266 | for (const r of refs) { |
| 267 | alreadyPresentRefs.add(`${sanitizeFileName(r.fileName)}:${r.mime}`) |
| 268 | } |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | // Filter out images already present in previous messages to avoid duplicates; keep (image, upload) pairs so indices stay aligned |
| 273 | const uniquePairs: { image: MessageContentImageUrl; upload: IFileUpload }[] = [] |
| 274 | images.forEach((image, index) => { |
| 275 | const upload = imageUploads[index] |
| 276 | if (upload && alreadyPresentRefs.has(`${sanitizeFileName(upload.name)}:${upload.mime}`)) { |
| 277 | return |
| 278 | } |
| 279 | const alreadyInContent = messages.some((msg) => { |
| 280 | const chatMsg = msg as IChatMessage |
| 281 | if (Array.isArray(chatMsg.content)) { |
| 282 | return chatMsg.content.some( |
| 283 | (item) => |
| 284 | (item as IMultimodalContentItem).type === 'image_url' && |
| 285 | image.type === 'image_url' && |
| 286 | JSON.stringify(item) === JSON.stringify(image) |
| 287 | ) |
| 288 | } |
| 289 | return JSON.stringify(chatMsg.content) === JSON.stringify(image) |
| 290 | }) |
| 291 | if (!alreadyInContent) uniquePairs.push({ image, upload }) |
| 292 | }) |
| 293 | |
| 294 | const uniqueImages = uniquePairs.map((p) => p.image) |
| 295 | |
| 296 | if (uniqueImages.length === 0) return undefined |
| 297 | |
| 298 | // File-ref version: lightweight references for storage (only unique uploads) |
| 299 | const imageMessageWithFileRef: IChatMessage = { |
| 300 | role: 'user', |
| 301 | content: uniquePairs.map(({ upload }) => ({ |
| 302 | type: upload.type, |
| 303 | name: sanitizeFileName(upload.name), |
| 304 | mime: upload.mime |
| 305 | })) as ContentBlock[] |
| 306 | } |
| 307 |
no test coverage detected