import { Buffer } from "node:buffer"; import { isDataUrl, parseDataUrl } from "../utils/dataUrl.js"; import { audioMimeType, extensionFromMimeType } from "../utils/mediaTypes.js"; function mediaUrl(publicBaseUrl, mediaId) { return `${publicBaseUrl}/v1/media/${mediaId}`; } export function createResponseNormalizationService({ mediaStore }) { return { normalize(body, { publicBaseUrl, audioFormat = "mp3", exposeMediaUrls = true } = {}) { if (!body || !exposeMediaUrls) { return body; } const normalized = structuredClone(body); const proxyMedia = []; for (const [choiceIndex, choice] of (normalized.choices ?? []).entries()) { const message = choice?.message; if (!message) { continue; } if (message.audio?.data) { const format = message.audio.format ?? audioFormat; const media = mediaStore.save({ buffer: Buffer.from(message.audio.data, "base64"), mimeType: audioMimeType(format), extension: format }); message.audio.format = format; message.audio.url = mediaUrl(publicBaseUrl, media.id); proxyMedia.push({ choice: choiceIndex, type: "audio", url: message.audio.url }); } if (!Array.isArray(message.content)) { continue; } for (const [partIndex, part] of message.content.entries()) { const imageUrl = part?.image_url?.url; if (!isDataUrl(imageUrl)) { continue; } const parsed = parseDataUrl(imageUrl); if (!parsed) { continue; } const media = mediaStore.save({ buffer: Buffer.from(parsed.base64, "base64"), mimeType: parsed.mimeType, extension: extensionFromMimeType(parsed.mimeType) }); part.image_url.proxy_url = mediaUrl(publicBaseUrl, media.id); proxyMedia.push({ choice: choiceIndex, part: partIndex, type: "image", url: part.image_url.proxy_url }); } } if (proxyMedia.length > 0) { normalized.proxy = { media: proxyMedia }; } return normalized; } }; }