Skip to content

Commit 098bffb

Browse files
authored
Merge branch 'openai:main' into main
2 parents e23e7af + 741da67 commit 098bffb

28 files changed

+3856
-178
lines changed

.vscode/launch.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Python Debugger: Python File",
9+
"type": "debugpy",
10+
"request": "launch",
11+
"program": "${file}"
12+
}
13+
]
14+
}

examples/agent_patterns/llm_as_a_judge.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class EvaluationFeedback:
3232
instructions=(
3333
"You evaluate a story outline and decide if it's good enough."
3434
"If it's not good enough, you provide feedback on what needs to be improved."
35-
"Never give it a pass on the first try. after 5 attempts, you can give it a pass if story outline is good enough - do not go for perfection"
35+
"Never give it a pass on the first try. After 5 attempts, you can give it a pass if story outline is good enough - do not go for perfection"
3636
),
3737
output_type=EvaluationFeedback,
3838
)

examples/realtime/demo.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import asyncio
2+
import os
3+
import sys
4+
from typing import TYPE_CHECKING
5+
6+
import numpy as np
7+
8+
from agents.realtime import RealtimeSession
9+
10+
# Add the current directory to path so we can import ui
11+
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
12+
13+
from agents import function_tool
14+
from agents.realtime import RealtimeAgent, RealtimeRunner, RealtimeSessionEvent
15+
16+
if TYPE_CHECKING:
17+
from .ui import AppUI
18+
else:
19+
# Try both import styles
20+
try:
21+
# Try relative import first (when used as a package)
22+
from .ui import AppUI
23+
except ImportError:
24+
# Fall back to direct import (when run as a script)
25+
from ui import AppUI
26+
27+
28+
@function_tool
29+
def get_weather(city: str) -> str:
30+
"""Get the weather in a city."""
31+
return f"The weather in {city} is sunny."
32+
33+
34+
agent = RealtimeAgent(
35+
name="Assistant",
36+
instructions="You always greet the user with 'Top of the morning to you'.",
37+
tools=[get_weather],
38+
)
39+
40+
41+
class Example:
42+
def __init__(self) -> None:
43+
self.ui = AppUI()
44+
self.ui.connected = asyncio.Event()
45+
self.ui.last_audio_item_id = None
46+
# Set the audio callback
47+
self.ui.set_audio_callback(self.on_audio_recorded)
48+
49+
self.session: RealtimeSession | None = None
50+
51+
async def run(self) -> None:
52+
# Start UI in a separate task instead of waiting for it to complete
53+
ui_task = asyncio.create_task(self.ui.run_async())
54+
55+
# Set up session immediately without waiting for UI to finish
56+
runner = RealtimeRunner(agent)
57+
async with await runner.run() as session:
58+
self.session = session
59+
self.ui.set_is_connected(True)
60+
async for event in session:
61+
await self.on_event(event)
62+
63+
# Wait for UI task to complete when session ends
64+
await ui_task
65+
66+
async def on_audio_recorded(self, audio_bytes: bytes) -> None:
67+
"""Called when audio is recorded by the UI."""
68+
try:
69+
# Send the audio to the session
70+
assert self.session is not None
71+
await self.session.send_audio(audio_bytes)
72+
except Exception as e:
73+
self.ui.log_message(f"Error sending audio: {e}")
74+
75+
async def on_event(self, event: RealtimeSessionEvent) -> None:
76+
# Display event in the UI
77+
try:
78+
if event.type == "agent_start":
79+
self.ui.add_transcript(f"Agent started: {event.agent.name}")
80+
elif event.type == "agent_end":
81+
self.ui.add_transcript(f"Agent ended: {event.agent.name}")
82+
elif event.type == "handoff":
83+
self.ui.add_transcript(
84+
f"Handoff from {event.from_agent.name} to {event.to_agent.name}"
85+
)
86+
elif event.type == "tool_start":
87+
self.ui.add_transcript(f"Tool started: {event.tool.name}")
88+
elif event.type == "tool_end":
89+
self.ui.add_transcript(f"Tool ended: {event.tool.name}; output: {event.output}")
90+
elif event.type == "audio_end":
91+
self.ui.add_transcript("Audio ended")
92+
elif event.type == "audio":
93+
np_audio = np.frombuffer(event.audio.data, dtype=np.int16)
94+
self.ui.play_audio(np_audio)
95+
elif event.type == "audio_interrupted":
96+
self.ui.add_transcript("Audio interrupted")
97+
elif event.type == "error":
98+
self.ui.add_transcript(f"Error: {event.error}")
99+
elif event.type == "history_updated":
100+
pass
101+
elif event.type == "history_added":
102+
pass
103+
elif event.type == "raw_model_event":
104+
self.ui.log_message(f"Raw model event: {event.data}")
105+
else:
106+
self.ui.log_message(f"Unknown event type: {event.type}")
107+
except Exception as e:
108+
# This can happen if the UI has already exited
109+
self.ui.log_message(f"Event handling error: {str(e)}")
110+
111+
112+
if __name__ == "__main__":
113+
example = Example()
114+
asyncio.run(example.run())

0 commit comments

Comments
 (0)