File size: 2,327 Bytes
e43a4a9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 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;
}
};
}
|