Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/agents/voice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
StreamedTranscriptionSession,
STTModel,
STTModelSettings,
TTSCustomVoice,
TTSModel,
TTSModelSettings,
TTSVoice,
Expand All @@ -29,6 +30,7 @@
"StreamedAudioInput",
"STTModel",
"STTModelSettings",
"TTSCustomVoice",
"TTSModel",
"TTSModelSettings",
"TTSVoice",
Expand Down
45 changes: 29 additions & 16 deletions src/agents/voice/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from dataclasses import dataclass
from typing import Any, Literal

from typing_extensions import TypedDict

from .imports import np, npt
from .input import AudioInput, StreamedAudioInput
from .utils import get_sentence_based_splitter
Expand All @@ -14,22 +16,33 @@
)
DEFAULT_TTS_BUFFER_SIZE = 120

TTSVoice = Literal[
"alloy",
"ash",
"ballad",
"coral",
"echo",
"fable",
"onyx",
"nova",
"sage",
"shimmer",
"verse",
"marin",
"cedar",
]
"""Exportable type for the TTSModelSettings voice enum"""

class TTSCustomVoice(TypedDict):
"""A custom OpenAI TTS voice reference."""

id: str
"""The custom voice ID."""


TTSVoice = (
Literal[
"alloy",
"ash",
"ballad",
"coral",
"echo",
"fable",
"onyx",
"nova",
"sage",
"shimmer",
"verse",
"marin",
"cedar",
]
| TTSCustomVoice
)
"""Exportable type for built-in TTS voices and custom voice IDs."""


@dataclass
Expand Down
24 changes: 21 additions & 3 deletions tests/voice/test_tts_voice_types.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
from typing import get_args
from typing import Literal, get_args, get_origin

from agents.voice.model import TTSVoice
import agents.voice as voice
from agents.voice import TTSCustomVoice, TTSModelSettings, TTSVoice


def _builtin_voice_values() -> set[str]:
literal_type = next(arg for arg in get_args(TTSVoice) if get_origin(arg) is Literal)
return set(get_args(literal_type))


def test_tts_voice_type_includes_current_openai_builtin_voices() -> None:
assert {"ballad", "verse", "marin", "cedar"} <= set(get_args(TTSVoice))
assert {"ballad", "verse", "marin", "cedar"} <= _builtin_voice_values()


def test_tts_voice_type_accepts_custom_voice_ids() -> None:
custom_voice: TTSCustomVoice = {"id": "voice_1234"}
settings = TTSModelSettings(voice=custom_voice)

assert TTSCustomVoice in get_args(TTSVoice)
assert settings.voice == {"id": "voice_1234"}


def test_tts_custom_voice_is_exported_from_agents_voice() -> None:
assert "TTSCustomVoice" in voice.__all__
Loading