63 lines
1.7 KiB
Python
63 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Multi-turn conversational test: two back-and-forth exchanges over /ws."""
|
|
import asyncio
|
|
import json
|
|
import sys
|
|
|
|
sys.path.insert(0, "/opt/collector")
|
|
from app import TTS, CFG
|
|
import websockets
|
|
|
|
tts = TTS(CFG["tts"])
|
|
tts.load()
|
|
P1 = tts.synthesize_16k("What is your name?")
|
|
P2 = tts.synthesize_16k("Tell me something interesting.")
|
|
|
|
FRAME = 640 # 20ms @ 16kHz
|
|
|
|
|
|
async def send_utterance(ws, pcm):
|
|
for i in range(0, len(pcm), FRAME):
|
|
await ws.send(pcm[i:i + FRAME])
|
|
await asyncio.sleep(0.02)
|
|
silence = b"\x00" * FRAME
|
|
for _ in range(50): # 1s silence -> VAD turn end
|
|
await ws.send(silence)
|
|
await asyncio.sleep(0.02)
|
|
|
|
|
|
async def read_reply(ws, seen_assistant):
|
|
"""Read messages until we collect a NEW assistant transcript + audio."""
|
|
audio = 0
|
|
while True:
|
|
try:
|
|
msg = await asyncio.wait_for(ws.recv(), timeout=45)
|
|
except Exception:
|
|
return False
|
|
if isinstance(msg, str):
|
|
m = json.loads(msg)
|
|
if m.get("role") == "assistant":
|
|
seen_assistant += 1
|
|
else:
|
|
audio += len(msg)
|
|
if seen_assistant >= 1 and audio > 0:
|
|
return True
|
|
|
|
|
|
async def main():
|
|
async with websockets.connect("ws://127.0.0.1:8766/ws") as ws:
|
|
await asyncio.sleep(6) # warm
|
|
# Turn 1
|
|
await send_utterance(ws, P1)
|
|
ok1 = await read_reply(ws, 0)
|
|
print("TURN1 reply:", "PASS" if ok1 else "FAIL")
|
|
# Turn 2
|
|
await asyncio.sleep(1)
|
|
await send_utterance(ws, P2)
|
|
ok2 = await read_reply(ws, 1)
|
|
print("TURN2 reply:", "PASS" if ok2 else "FAIL")
|
|
print("MULTITURN", "PASS" if (ok1 and ok2) else "FAIL")
|
|
|
|
|
|
asyncio.run(main())
|