import test from 'node:test'; import assert from 'node:assert/strict'; import { once } from 'node:events'; import { WebSocketServer, WebSocket } from 'ws'; // Local upstreams exercise the real framing without provider credentials or network access. test('one PCM turn streams through Scribe and dialogue TTS', async () => { const stt = new WebSocketServer({ port: 0 }); const tts = new WebSocketServer({ port: 0 }); await Promise.all([once(stt, 'listening'), once(tts, 'listening')]); process.env.ELEVENLABS_API_KEY = 'test'; process.env.LLM_MODE = 'echo'; process.env.ELEVEN_STT_URL = `ws://127.0.0.1:${stt.address().port}/stt`; process.env.ELEVEN_TTS_URL = `ws://127.0.0.1:${tts.address().port}/tts`; let input = Buffer.alloc(0), ttsText = '', recorded; stt.on('connection', (ws, req) => { assert.equal(new URL(req.url, 'http://x').searchParams.get('commit_strategy'), 'manual'); ws.on('message', data => { const msg = JSON.parse(data); input = Buffer.concat([input, Buffer.from(msg.audio_base_64, 'base64')]); if (msg.commit) ws.send(JSON.stringify({ message_type: 'committed_transcript', text: 'Привет' })); }); }); tts.on('connection', ws => ws.on('message', data => { const msg = JSON.parse(data); if (msg.inputs) ttsText += msg.inputs[0].text; if (msg.close_socket) { ws.send(JSON.stringify({ audio: Buffer.from([1, 2, 3, 4]).toString('base64') })); ws.send(JSON.stringify({ is_final: true })); } })); const { handleTurn } = await import('../server/turns.mjs'); const local = new WebSocketServer({ port: 0 }); await once(local, 'listening'); const store = { getSettings: () => ({ sttModel: 'scribe_v2_realtime', ttsModel: 'eleven_v4_turbo', voiceId: 'voice', systemPrompt: '' }), getHistory: () => [], recordTurn: (...args) => { recorded = args; } }; local.on('connection', ws => handleTurn(ws, store)); const client = new WebSocket(`ws://127.0.0.1:${local.address().port}`); const seen = [], audio = []; client.on('message', (data, binary) => { if (binary) audio.push(...data); else { const msg = JSON.parse(data); seen.push(msg.type); if (msg.type === 'ready') { client.send(JSON.stringify({ type: 'start' })); client.send(Buffer.from([5, 6, 7, 8])); client.send(JSON.stringify({ type: 'end' })); } } }); await once(client, 'close'); assert.deepEqual(seen, ['ready', 'transcript', 'done']); assert.deepEqual([...input], [5, 6, 7, 8]); assert.deepEqual(audio, [1, 2, 3, 4]); assert.equal(ttsText, 'Привет'); assert.deepEqual(recorded, ['Привет', 'Привет']); await Promise.all([new Promise(r => local.close(r)), new Promise(r => stt.close(r)), new Promise(r => tts.close(r))]); });