test_PR349 / src /reachy_mini_conversation_app /conversation_handler.py
alozowski's picture
alozowski HF Staff
Sync from GitHub via hub-sync
8c424b3 verified
Raw
History Blame Contribute Delete
1.89 kB
from __future__ import annotations
import asyncio
from abc import ABC, abstractmethod
from typing import TypeAlias
from collections.abc import Callable
import numpy as np
from fastrtc import AdditionalOutputs, AsyncStreamHandler
from numpy.typing import NDArray
from reachy_mini_conversation_app.tools.core_tools import ToolDependencies
AudioFrame: TypeAlias = tuple[int, NDArray[np.int16]]
HandlerOutput: TypeAlias = AudioFrame | AdditionalOutputs | None
QueueItem: TypeAlias = AudioFrame | AdditionalOutputs
class ConversationHandler(AsyncStreamHandler, ABC):
"""Shared app handler contract for realtime conversation backends."""
deps: ToolDependencies
output_queue: asyncio.Queue[QueueItem]
_clear_queue: Callable[[], None] | None
@abstractmethod
def copy(self) -> ConversationHandler:
"""Create a copy of the handler."""
...
@abstractmethod
async def start_up(self) -> None:
"""Start the realtime handler."""
...
@abstractmethod
async def shutdown(self) -> None:
"""Shut down the realtime handler."""
...
@abstractmethod
async def receive(self, frame: AudioFrame) -> None:
"""Receive an input audio frame."""
...
@abstractmethod
async def emit(self) -> HandlerOutput:
"""Emit the next output item."""
...
@abstractmethod
async def apply_personality(self, profile: str | None) -> str:
"""Apply a personality profile."""
...
@abstractmethod
async def get_available_voices(self) -> list[str]:
"""Return voices available for the active backend."""
...
@abstractmethod
def get_current_voice(self) -> str:
"""Return the current voice."""
...
@abstractmethod
async def change_voice(self, voice: str) -> str:
"""Change the current voice."""
...