Skip to content

Commit f92b561

Browse files
authored
Realtime: make example customizable: (#1332)
Trying to make it easy to customize/use your own agents and reuse the UI.
1 parent 473e0a2 commit f92b561

File tree

3 files changed

+58
-29
lines changed

3 files changed

+58
-29
lines changed

examples/realtime/app/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ cd examples/realtime/app && uv run python server.py
2020

2121
Then open your browser to: http://localhost:8000
2222

23+
## Customization
24+
25+
To use the same UI with your own agents, edit `agent.py` and ensure get_starting_agent() returns the right starting agent for your use case.
26+
2327
## How to Use
2428

2529
1. Click **Connect** to establish a realtime session

examples/realtime/app/agent.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from agents import function_tool
2+
from agents.realtime import RealtimeAgent
3+
4+
"""
5+
When running the UI example locally, you can edit this file to change the setup. THe server
6+
will use the agent returned from get_starting_agent() as the starting agent."""
7+
8+
9+
@function_tool
10+
def get_weather(city: str) -> str:
11+
"""Get the weather in a city."""
12+
return f"The weather in {city} is sunny."
13+
14+
15+
@function_tool
16+
def get_secret_number() -> int:
17+
"""Returns the secret number, if the user asks for it."""
18+
return 71
19+
20+
21+
haiku_agent = RealtimeAgent(
22+
name="Haiku Agent",
23+
instructions="You are a haiku poet. You must respond ONLY in traditional haiku format (5-7-5 syllables). Every response should be a proper haiku about the topic. Do not break character.",
24+
tools=[],
25+
)
26+
27+
assistant_agent = RealtimeAgent(
28+
name="Assistant",
29+
instructions="If the user wants poetry or haikus, you can hand them off to the haiku agent via the transfer_to_haiku_agent tool.",
30+
tools=[get_weather, get_secret_number],
31+
handoffs=[haiku_agent],
32+
)
33+
34+
35+
def get_starting_agent() -> RealtimeAgent:
36+
return assistant_agent

examples/realtime/app/server.py

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,30 @@
44
import logging
55
import struct
66
from contextlib import asynccontextmanager
7-
from typing import Any, assert_never
7+
from typing import TYPE_CHECKING, Any, assert_never
88

99
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
1010
from fastapi.responses import FileResponse
1111
from fastapi.staticfiles import StaticFiles
1212

13-
from agents import function_tool
14-
from agents.realtime import RealtimeAgent, RealtimeRunner, RealtimeSession, RealtimeSessionEvent
15-
16-
logging.basicConfig(level=logging.INFO)
17-
logger = logging.getLogger(__name__)
18-
19-
20-
@function_tool
21-
def get_weather(city: str) -> str:
22-
"""Get the weather in a city."""
23-
return f"The weather in {city} is sunny."
24-
25-
26-
@function_tool
27-
def get_secret_number() -> int:
28-
"""Returns the secret number, if the user asks for it."""
29-
return 71
13+
from agents.realtime import RealtimeRunner, RealtimeSession, RealtimeSessionEvent
3014

15+
# Import TwilioHandler class - handle both module and package use cases
16+
if TYPE_CHECKING:
17+
# For type checking, use the relative import
18+
from .agent import get_starting_agent
19+
else:
20+
# At runtime, try both import styles
21+
try:
22+
# Try relative import first (when used as a package)
23+
from .agent import get_starting_agent
24+
except ImportError:
25+
# Fall back to direct import (when run as a script)
26+
from agent import get_starting_agent
3127

32-
haiku_agent = RealtimeAgent(
33-
name="Haiku Agent",
34-
instructions="You are a haiku poet. You must respond ONLY in traditional haiku format (5-7-5 syllables). Every response should be a proper haiku about the topic. Do not break character.",
35-
tools=[],
36-
)
3728

38-
agent = RealtimeAgent(
39-
name="Assistant",
40-
instructions="If the user wants poetry or haikus, you can hand them off to the haiku agent via the transfer_to_haiku_agent tool.",
41-
tools=[get_weather, get_secret_number],
42-
handoffs=[haiku_agent],
43-
)
29+
logging.basicConfig(level=logging.INFO)
30+
logger = logging.getLogger(__name__)
4431

4532

4633
class RealtimeWebSocketManager:
@@ -53,6 +40,7 @@ async def connect(self, websocket: WebSocket, session_id: str):
5340
await websocket.accept()
5441
self.websockets[session_id] = websocket
5542

43+
agent = get_starting_agent()
5644
runner = RealtimeRunner(agent)
5745
session_context = await runner.run()
5846
session = await session_context.__aenter__()
@@ -150,6 +138,7 @@ async def websocket_endpoint(websocket: WebSocket, session_id: str):
150138

151139
if message["type"] == "audio":
152140
# Convert int16 array to bytes
141+
print("Received audio data")
153142
int16_data = message["data"]
154143
audio_bytes = struct.pack(f"{len(int16_data)}h", *int16_data)
155144
await manager.send_audio(session_id, audio_bytes)

0 commit comments

Comments
 (0)