With LiveKit

Already running voice agents on LiveKit? The livekit-plugins-phonic plugin plugs Phonic’s realtime speech-to-speech model into LiveKit Agents, so you can switch providers without changing your LiveKit setup.

Installation

$uv add livekit-plugins-phonic

Usage

1import asyncio
2import logging
3
4from dotenv import load_dotenv
5
6from livekit.agents import (
7 Agent,
8 AgentServer,
9 AgentSession,
10 JobContext,
11 cli,
12 function_tool,
13)
14from livekit.plugins.phonic.realtime import RealtimeModel
15
16logger = logging.getLogger("phonic-agent")
17
18load_dotenv()
19
20
21class MyAgent(Agent):
22 def __init__(self) -> None:
23 super().__init__(
24 instructions="You are a helpful voice AI assistant named Sabrina.",
25 llm=RealtimeModel(
26 voice="sabrina",
27 audio_speed=1.2,
28 ),
29 )
30
31 @function_tool(
32 description="Toggle a light on or off. Available lights are A05, A06, A07, and A08."
33 )
34 async def toggle_light(self, light_id: str, state: str) -> str:
35 """Called when the user asks to toggle a light on or off.
36
37 Args:
38 light_id: The ID of the light to toggle
39 state: Whether to turn the light on or off, e.g., 'on', 'off'
40 """
41 logger.info(f"Turning {state} light {light_id}")
42 await asyncio.sleep(1.0)
43 return f"Light {light_id} turned {state}"
44
45
46server = AgentServer()
47
48
49@server.rtc_session()
50async def entrypoint(ctx: JobContext):
51 session = AgentSession()
52 await session.start(agent=MyAgent(), room=ctx.room)
53 await session.generate_reply(
54 instructions="Greet the user, asking about their day.",
55 )
56
57
58if __name__ == "__main__":
59 cli.run_app(server)

Configuration

Set the PHONIC_API_KEY environment variable, or pass api_key directly to RealtimeModel. All other options are optional.

OptionTypeDescription
api_keystrPhonic API key. Falls back to PHONIC_API_KEY environment variable
phonic_agentstrPhonic agent name. Options set explicitly here override agent settings
voicestrVoice ID — sabrina, grant, virginia, landon, eleanor, shelby, nolan
welcome_messagestrMessage the agent says when the conversation starts. Ignored when generate_welcome_message is True
generate_welcome_messageboolAuto-generate the welcome message (ignores welcome_message)
projectstrProject name (default: main)
default_languagestrISO 639-1 default language for recognition and speech
additional_languageslist[str]Further ISO 639-1 codes (must not repeat default_language)
multilingual_mode"auto" | "request"Per-utterance language detection vs. change on user request (recommended: request)
audio_speedfloatAudio playback speed
phonic_toolslist[str]Phonic Webhook tool names available to the assistant
boosted_keywordslist[str]Keywords to boost in speech recognition
min_words_to_interruptintMinimum number of user words required to interrupt the assistant
generate_no_input_poke_textboolAuto-generate poke text when user is silent
no_input_poke_secfloatSeconds of silence before sending poke message
no_input_poke_textstrPoke message text (ignored when generate_no_input_poke_text is True)
no_input_end_conversation_secfloatSeconds of silence before ending conversation
forbid_speech_after_tool_calllist[str]Tool names after which Phonic should NOT auto-generate a spoken reply. Use for tools that always hand off/trigger an agent switch

If you already have an agent set up on the Phonic platform, you can use the phonic_agent option to specify the agent name. As a note, configuration options you set in the LiveKit Agents SDK will override the agent settings set on the Phonic platform. This means the system prompt you have set on the Phonic platform will be ignored in favor of the instructions field set on the LiveKit Agent. Likewise, options explicitly set in the RealtimeModel constructor will override the Phonic agent’s settings.

If you have Webhook tools set up on the Phonic platform, you can use phonic_tools to make them available to your agent.