Initial commit: audio-chat with fixes

- Created AGENTS.md with architecture documentation
- Fixed race conditions and async patterns
- Added conversation history to LLM prompts
- Fixed TTS audio shape handling
- Added buffer limits and graceful shutdown
- Fixed client.py with file sending support
- Removed duplicate requirements
- Added .gitignore
This commit is contained in:
2026-05-01 13:01:06 +00:00
commit 1edfd5d62f
13 changed files with 1286 additions and 0 deletions

0
audio/__init__.py Normal file
View File

50
audio/stream.py Normal file
View File

@@ -0,0 +1,50 @@
import threading
import time
from config import Config
class AudioStreamBuffer:
def __init__(self):
self.config = Config()
self.buffer = b""
self.lock = threading.Lock()
self.event = threading.Event()
self.running = False
# Limit buffer to 10 seconds of audio to prevent OOM
self.max_buffer_bytes = int(self.config.SAMPLE_RATE * 10 * 2)
def start(self):
self.running = True
self.buffer = b""
self.event.clear()
def add_chunk(self, chunk: bytes):
with self.lock:
self.buffer += chunk
# Evict oldest data if buffer exceeds limit
if len(self.buffer) > self.max_buffer_bytes:
self.buffer = self.buffer[-self.max_buffer_bytes // 2:]
if len(self.buffer) >= self.config.CHUNK_SIZE:
self.event.set()
def get_ready_chunk(self, timeout: float = 1.0) -> bytes:
if self.event.wait(timeout=timeout):
with self.lock:
chunk = self.buffer
self.buffer = b""
self.event.clear()
return chunk
return b""
def get_full_buffer(self) -> bytes:
with self.lock:
chunk = self.buffer
self.buffer = b""
return chunk
def stop(self):
self.running = False
self.event.set()
def is_running(self):
return self.running