oapix / src /services /responseNormalizationService.js
woiceatus's picture
init
e43a4a9
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;
}
};
}