| import test from "node:test"; | |
| import assert from "node:assert/strict"; | |
| import { createRequestNormalizationService } from "../src/services/requestNormalizationService.js"; | |
| test("normalizes audio URLs to mp3 base64 and raw image base64 to data URLs", async () => { | |
| const service = createRequestNormalizationService({ | |
| audioConversionService: { | |
| async downloadAndConvertToMp3Base64(url) { | |
| assert.equal(url, "https://example.com/sample.wav"); | |
| return { | |
| data: "ZmFrZS1tcDM=", | |
| format: "mp3" | |
| }; | |
| }, | |
| async normalizeBase64Audio(audio) { | |
| return audio; | |
| } | |
| } | |
| }); | |
| const { normalizedBody, responseContext } = await service.normalize({ | |
| messages: [ | |
| { | |
| role: "user", | |
| content: [ | |
| { | |
| type: "image_url", | |
| image_url: { | |
| url: "iVBORw0KGgoAAAANSUhEUgAAAAUA" | |
| }, | |
| mime_type: "image/png" | |
| }, | |
| { | |
| type: "input_audio", | |
| input_audio: { | |
| url: "https://example.com/sample.wav" | |
| } | |
| } | |
| ] | |
| } | |
| ], | |
| audio: { | |
| format: "wav" | |
| } | |
| }); | |
| assert.equal(normalizedBody.messages[0].content[0].image_url.url.startsWith("data:image/png;base64,"), true); | |
| assert.deepEqual(normalizedBody.messages[0].content[1], { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "ZmFrZS1tcDM=", | |
| format: "mp3" | |
| } | |
| }); | |
| assert.equal(responseContext.audioFormat, "wav"); | |
| }); | |
| test("downloads remote audio when the URL is provided in input_audio.data", async () => { | |
| const service = createRequestNormalizationService({ | |
| audioConversionService: { | |
| async downloadAndConvertToMp3Base64(url) { | |
| assert.equal(url, "https://example.com/sample.mp4"); | |
| return { | |
| data: "ZG93bmxvYWRlZC1hbmQtY29udmVydGVk", | |
| format: "mp3" | |
| }; | |
| }, | |
| async normalizeBase64Audio() { | |
| throw new Error("unexpected base64 conversion"); | |
| } | |
| } | |
| }); | |
| const { normalizedBody } = await service.normalize({ | |
| messages: [ | |
| { | |
| role: "user", | |
| content: [ | |
| { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "https://example.com/sample.mp4", | |
| format: "m4a" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }); | |
| assert.deepEqual(normalizedBody.messages[0].content[0], { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "ZG93bmxvYWRlZC1hbmQtY29udmVydGVk", | |
| format: "mp3" | |
| } | |
| }); | |
| }); | |
| test("normalizes uploaded wav audio before forwarding upstream", async () => { | |
| const service = createRequestNormalizationService({ | |
| audioConversionService: { | |
| async downloadAndConvertToMp3Base64() { | |
| throw new Error("unexpected url conversion"); | |
| }, | |
| async normalizeBase64Audio(audio) { | |
| assert.deepEqual(audio, { | |
| data: "UklGRl8AAABXQVZFZm10", | |
| format: "wav" | |
| }); | |
| return { | |
| data: "bm9ybWFsaXplZC13YXY=", | |
| format: "wav" | |
| }; | |
| } | |
| } | |
| }); | |
| const { normalizedBody } = await service.normalize({ | |
| messages: [ | |
| { | |
| role: "user", | |
| content: [ | |
| { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "UklGRl8AAABXQVZFZm10", | |
| format: "wav" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }); | |
| assert.deepEqual(normalizedBody.messages[0].content[0], { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "bm9ybWFsaXplZC13YXY=", | |
| format: "wav" | |
| } | |
| }); | |
| }); | |
| test("preserves uploaded m4a format for conversion and forwards mp3 output", async () => { | |
| const service = createRequestNormalizationService({ | |
| audioConversionService: { | |
| async downloadAndConvertToMp3Base64() { | |
| throw new Error("unexpected url conversion"); | |
| }, | |
| async normalizeBase64Audio(audio) { | |
| assert.deepEqual(audio, { | |
| data: "AAAAGGZ0eXBNNEEg", | |
| format: "m4a" | |
| }); | |
| return { | |
| data: "Y29udmVydGVkLW1wMw==", | |
| format: "mp3" | |
| }; | |
| } | |
| } | |
| }); | |
| const { normalizedBody } = await service.normalize({ | |
| messages: [ | |
| { | |
| role: "user", | |
| content: [ | |
| { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "AAAAGGZ0eXBNNEEg", | |
| format: "m4a" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }); | |
| assert.deepEqual(normalizedBody.messages[0].content[0], { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "Y29udmVydGVkLW1wMw==", | |
| format: "mp3" | |
| } | |
| }); | |
| }); | |
| test("parses m4a data urls with codec metadata before conversion", async () => { | |
| const service = createRequestNormalizationService({ | |
| audioConversionService: { | |
| async downloadAndConvertToMp3Base64() { | |
| throw new Error("unexpected url conversion"); | |
| }, | |
| async normalizeBase64Audio(audio) { | |
| assert.deepEqual(audio, { | |
| data: "AAAAGGZ0eXBNNEEg", | |
| format: "m4a" | |
| }); | |
| return { | |
| data: "Y29udmVydGVkLW1wMw==", | |
| format: "mp3" | |
| }; | |
| } | |
| } | |
| }); | |
| const { normalizedBody } = await service.normalize({ | |
| messages: [ | |
| { | |
| role: "user", | |
| content: [ | |
| { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "data:audio/mp4;codecs=mp4a.40.2;base64,AAAAGGZ0eXBNNEEg", | |
| format: "m4a" | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| }); | |
| assert.deepEqual(normalizedBody.messages[0].content[0], { | |
| type: "input_audio", | |
| input_audio: { | |
| data: "Y29udmVydGVkLW1wMw==", | |
| format: "mp3" | |
| } | |
| }); | |
| }); | |