fix long run bug
This commit is contained in:
@@ -17,6 +17,7 @@ import argparse
|
||||
import asyncio
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
import queue
|
||||
from pathlib import Path
|
||||
@@ -92,6 +93,14 @@ class MicrophoneClient:
|
||||
# State
|
||||
self.is_recording = True
|
||||
self.is_playing = True
|
||||
|
||||
# TTFB tracking (Time to First Byte)
|
||||
self.request_start_time = None
|
||||
self.first_audio_received = False
|
||||
|
||||
# Interrupt handling - discard audio until next trackStart
|
||||
self._discard_audio = False
|
||||
self._audio_sequence = 0 # Track audio sequence to detect stale chunks
|
||||
|
||||
async def connect(self) -> None:
|
||||
"""Connect to WebSocket server."""
|
||||
@@ -117,6 +126,10 @@ class MicrophoneClient:
|
||||
|
||||
async def send_chat(self, text: str) -> None:
|
||||
"""Send chat message (text input)."""
|
||||
# Reset TTFB tracking for new request
|
||||
self.request_start_time = time.time()
|
||||
self.first_audio_received = False
|
||||
|
||||
await self.send_command({
|
||||
"command": "chat",
|
||||
"text": text
|
||||
@@ -236,9 +249,21 @@ class MicrophoneClient:
|
||||
# Audio data received
|
||||
self.bytes_received += len(message)
|
||||
|
||||
# Check if we should discard this audio (after interrupt)
|
||||
if self._discard_audio:
|
||||
duration_ms = len(message) / (self.sample_rate * 2) * 1000
|
||||
print(f"← Audio: {duration_ms:.0f}ms (DISCARDED - waiting for new track)")
|
||||
continue
|
||||
|
||||
if self.is_playing:
|
||||
self._add_audio_to_buffer(message)
|
||||
|
||||
# Calculate and display TTFB for first audio packet
|
||||
if not self.first_audio_received and self.request_start_time:
|
||||
client_ttfb_ms = (time.time() - self.request_start_time) * 1000
|
||||
self.first_audio_received = True
|
||||
print(f"← [TTFB] Client first audio latency: {client_ttfb_ms:.0f}ms")
|
||||
|
||||
# Show progress (less verbose)
|
||||
with self.audio_output_lock:
|
||||
buffer_ms = len(self.audio_output_buffer) / (self.sample_rate * 2) * 1000
|
||||
@@ -285,20 +310,36 @@ class MicrophoneClient:
|
||||
# Interim result - show with indicator (overwrite same line)
|
||||
display_text = text[:60] + "..." if len(text) > 60 else text
|
||||
print(f" [listening] {display_text}".ljust(80), end="\r")
|
||||
elif event_type == "ttfb":
|
||||
# Server-side TTFB event
|
||||
latency_ms = event.get("latencyMs", 0)
|
||||
print(f"← [TTFB] Server reported latency: {latency_ms}ms")
|
||||
elif event_type == "trackStart":
|
||||
print("← Bot started speaking")
|
||||
# IMPORTANT: Accept audio again after trackStart
|
||||
self._discard_audio = False
|
||||
self._audio_sequence += 1
|
||||
# Reset TTFB tracking for voice responses (when no chat was sent)
|
||||
if self.request_start_time is None:
|
||||
self.request_start_time = time.time()
|
||||
self.first_audio_received = False
|
||||
# Clear any old audio in buffer
|
||||
with self.audio_output_lock:
|
||||
self.audio_output_buffer = b""
|
||||
elif event_type == "trackEnd":
|
||||
print("← Bot finished speaking")
|
||||
# Reset TTFB tracking after response completes
|
||||
self.request_start_time = None
|
||||
self.first_audio_received = False
|
||||
elif event_type == "interrupt":
|
||||
print("← Bot interrupted!")
|
||||
# IMPORTANT: Clear audio buffer immediately on interrupt
|
||||
# IMPORTANT: Discard all audio until next trackStart
|
||||
self._discard_audio = True
|
||||
# Clear audio buffer immediately
|
||||
with self.audio_output_lock:
|
||||
buffer_ms = len(self.audio_output_buffer) / (self.sample_rate * 2) * 1000
|
||||
self.audio_output_buffer = b""
|
||||
print(f" (cleared {buffer_ms:.0f}ms of buffered audio)")
|
||||
print(f" (cleared {buffer_ms:.0f}ms, discarding audio until new track)")
|
||||
elif event_type == "error":
|
||||
print(f"← Error: {event.get('error')}")
|
||||
elif event_type == "hangup":
|
||||
|
||||
Reference in New Issue
Block a user