import type { Server } from "node:http"; import { createServer } from "node:http"; import type { AddressInfo } from "node:net"; import { NoVoiceConfigured } from "@rakazo/adapters"; import type { Actor } from "@rakazo/contracts"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import type { VoiceDeps } from "./voice.js"; import { toVoiceStatus, transcribeVoice } from "./voice.js"; const actor: Actor = { userId: "user-1", spaceId: "space-1", email: "user@rakazo.test", isDeploymentOwner: false, }; /** A user without a voice credential, on a deployment whose media settings are `settings`. */ function deps(settings: object | null, ciphertext: string): VoiceDeps { return { prisma: { spaceVoicePreference: { findFirst: async () => null }, integrationProviderConfig: { findUnique: async () => (settings ? { id: "media", ciphertext } : null), }, }, secrets: { load: () => JSON.stringify(settings) }, } as unknown as VoiceDeps; } describe("dictation through the self-hosted transcription server", () => { let server: Server; let baseUrl = ""; const uploads: string[] = []; beforeAll(async () => { server = createServer((request, response) => { const chunks: Buffer[] = []; request.on("data", (chunk: Buffer) => chunks.push(chunk)); request.on("end", () => { uploads.push(`${request.url} ${Buffer.concat(chunks).toString("latin1")}`); response.setHeader("content-type", "application/json"); response.end(JSON.stringify({ text: " Remind me to call Ada. " })); }); }); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); baseUrl = `http://127.0.0.1:${(server.address() as AddressInfo).port}/v1`; }); afterAll(async () => { await new Promise((resolve) => server.close(resolve)); }); it("transcribes when no voice provider can", async () => { const result = await transcribeVoice( deps({ comfyui: null, transcription: { baseUrl } }, "media-a"), actor, { audio: new Uint8Array([1, 2, 3]), mimeType: "audio/webm;codecs=opus" }, ); expect(result).toEqual({ text: "Remind me to call Ada." }); expect(uploads[0]).toContain("/v1/audio/transcriptions"); expect(uploads[0]).toContain('filename="audio.webm"'); }); it("keeps asking for a voice key when no server is set up either", async () => { await expect( transcribeVoice(deps(null, "none"), actor, { audio: new Uint8Array([1]), mimeType: "audio/webm", }), ).rejects.toBeInstanceOf(NoVoiceConfigured); }); it("refuses an empty recording before uploading it", async () => { const before = uploads.length; await expect( transcribeVoice(deps({ comfyui: null, transcription: { baseUrl } }, "media-b"), actor, { audio: new Uint8Array(), mimeType: "audio/webm", }), ).rejects.toThrow("That recording is empty or too large."); expect(uploads).toHaveLength(before); }); it("reports server dictation in the voice status", () => { expect(toVoiceStatus(null).transcribe).toBe(false); expect(toVoiceStatus(null, { mediaTranscription: true })).toMatchObject({ configured: false, transcribe: true, }); }); });