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
3 changes: 2 additions & 1 deletion examples/homepage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ knowledge is loaded on demand through a generated `lookup_product` tool.
- `tests/unit/` is deterministic; `tests/evals/` runs live behavioral evaluations.

The voice pipeline uses LiveKit Inference with Gemma 4 31B, Deepgram Nova-3,
Inworld TTS, the LiveKit turn detector, and ai-coustics voice isolation.
Fish Audio S2.1 Pro in expressive mode, the LiveKit turn detector, and
ai-coustics voice isolation.

## Run locally

Expand Down
18 changes: 5 additions & 13 deletions examples/homepage/agent.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import logging
from collections.abc import AsyncIterable
from dataclasses import dataclass

from behaviors.frontend_attributes import publish_frontend_attributes
from behaviors.user_away import check_in_when_user_away
from dotenv import load_dotenv
from filters.pronunciation import pronounce_livekit
from knowledge_base import KnowledgeBase
from prompts import prompt

from livekit import rtc
from livekit.agents import (
Agent,
AgentServer,
AgentSession,
JobContext,
ModelSettings,
TurnHandlingOptions,
cli,
inference,
Expand All @@ -34,8 +30,9 @@ class AgentConfig:
llm_model: str = "google/gemma-4-31b-it"
stt_model: str = "deepgram/nova-3"
stt_language: str = "multi"
tts_model: str = "inworld/inworld-tts-2"
tts_voice: str = "Nate"
tts_model: str = "fishaudio/s2.1-pro"
tts_voice: str = "51b44863613e405a896f7f4294c6e6d0"
tts_voice_label: str = "Marley"


CONFIG = AgentConfig()
Expand All @@ -57,12 +54,6 @@ def __init__(
tools=[knowledge_base.lookup_tool()],
)

async def tts_node(
self, text: AsyncIterable[str], model_settings: ModelSettings
) -> AsyncIterable[rtc.AudioFrame]:
async for frame in Agent.default.tts_node(self, pronounce_livekit(text), model_settings):
yield frame

async def on_enter(self):
await self.session.generate_reply(
instructions=GREETING,
Expand All @@ -86,10 +77,11 @@ async def homepage_agent(ctx: JobContext):
turn_detection=inference.TurnDetector(),
),
preemptive_generation=True,
expressive=True,
)

check_in_when_user_away(session)
publish_frontend_attributes(tts_voice=CONFIG.tts_voice)
publish_frontend_attributes(tts_voice=CONFIG.tts_voice_label)

await session.start(
agent=Assistant(),
Expand Down
3 changes: 2 additions & 1 deletion examples/homepage/tests/unit/test_agent_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
def test_agent_config_is_the_single_source_of_runtime_identity() -> None:
assert AgentConfig() == CONFIG
assert CONFIG.name == "homepage_agent_v3"
assert CONFIG.tts_voice == "Nate"
assert CONFIG.tts_model == "fishaudio/s2.1-pro"
assert CONFIG.tts_voice_label == "Marley"

with pytest.raises(FrozenInstanceError):
CONFIG.tts_voice = "Alex" # type: ignore[misc]