Skip to content

Commit d8cb8b0

Browse files
committed
Broken handoff sample
1 parent 0e534bc commit d8cb8b0

File tree

3 files changed

+192
-0
lines changed

3 files changed

+192
-0
lines changed

samples-v2/openai_agents/function_app.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,11 @@ def tools(context):
102102
import basic.tools
103103
return basic.tools.main()
104104

105+
@app.orchestration_trigger(context_name="context")
106+
@durable_openai_agent_orchestrator
107+
def message_filter(context):
108+
import handoffs.message_filter
109+
return handoffs.message_filter.main()
110+
111+
105112

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
from __future__ import annotations
2+
3+
import json
4+
import random
5+
6+
from agents import Agent, HandoffInputData, Runner, function_tool, handoff
7+
from agents.extensions import handoff_filters
8+
9+
10+
@function_tool
11+
def random_number_tool(max: int) -> int:
12+
"""Return a random integer between 0 and the given maximum."""
13+
return random.randint(0, max)
14+
15+
16+
def spanish_handoff_message_filter(handoff_message_data: HandoffInputData) -> HandoffInputData:
17+
if is_gpt_5_default():
18+
print("gpt-5 is enabled, so we're not filtering the input history")
19+
# when using gpt-5, removing some of the items could break things, so we do this filtering only for other models
20+
return HandoffInputData(
21+
input_history=handoff_message_data.input_history,
22+
pre_handoff_items=tuple(handoff_message_data.pre_handoff_items),
23+
new_items=tuple(handoff_message_data.new_items),
24+
)
25+
26+
# First, we'll remove any tool-related messages from the message history
27+
handoff_message_data = handoff_filters.remove_all_tools(handoff_message_data)
28+
29+
# Second, we'll also remove the first two items from the history, just for demonstration
30+
history = (
31+
tuple(handoff_message_data.input_history[2:])
32+
if isinstance(handoff_message_data.input_history, tuple)
33+
else handoff_message_data.input_history
34+
)
35+
36+
# or, you can use the HandoffInputData.clone(kwargs) method
37+
return HandoffInputData(
38+
input_history=history,
39+
pre_handoff_items=tuple(handoff_message_data.pre_handoff_items),
40+
new_items=tuple(handoff_message_data.new_items),
41+
)
42+
43+
44+
first_agent = Agent(
45+
name="Assistant",
46+
instructions="Be extremely concise.",
47+
tools=[random_number_tool],
48+
)
49+
50+
spanish_agent = Agent(
51+
name="Spanish Assistant",
52+
instructions="You only speak Spanish and are extremely concise.",
53+
handoff_description="A Spanish-speaking assistant.",
54+
)
55+
56+
second_agent = Agent(
57+
name="Assistant",
58+
instructions=(
59+
"Be a helpful assistant. If the user speaks Spanish, handoff to the Spanish assistant."
60+
),
61+
handoffs=[handoff(spanish_agent, input_filter=spanish_handoff_message_filter)],
62+
)
63+
64+
65+
def main():
66+
# 1. Send a regular message to the first agent
67+
result = Runner.run_sync(first_agent, input="Hi, my name is Sora.")
68+
69+
print("Step 1 done")
70+
71+
# 2. Ask it to generate a number
72+
result = Runner.run_sync(
73+
first_agent,
74+
input=result.to_input_list()
75+
+ [{"content": "Can you generate a random number between 0 and 100?", "role": "user"}],
76+
)
77+
78+
print("Step 2 done")
79+
80+
# 3. Call the second agent
81+
result = Runner.run_sync(
82+
second_agent,
83+
input=result.to_input_list()
84+
+ [
85+
{
86+
"content": "I live in New York City. Whats the population of the city?",
87+
"role": "user",
88+
}
89+
],
90+
)
91+
92+
print("Step 3 done")
93+
94+
# 4. Cause a handoff to occur
95+
result = Runner.run_sync(
96+
second_agent,
97+
input=result.to_input_list()
98+
+ [
99+
{
100+
"content": "Por favor habla en español. ¿Cuál es mi nombre y dónde vivo?",
101+
"role": "user",
102+
}
103+
],
104+
)
105+
106+
print("Step 4 done")
107+
108+
print("\n===Final messages===\n")
109+
110+
# 5. That should have caused spanish_handoff_message_filter to be called, which means the
111+
# output should be missing the first two messages, and have no tool calls.
112+
# Let's print the messages to see what happened
113+
for message in result.to_input_list():
114+
print(json.dumps(message, indent=2))
115+
# tool_calls = message.tool_calls if isinstance(message, AssistantMessage) else None
116+
117+
# print(f"{message.role}: {message.content}\n - Tool calls: {tool_calls or 'None'}")
118+
"""
119+
$python examples/handoffs/message_filter.py
120+
Step 1 done
121+
Step 2 done
122+
Step 3 done
123+
Step 4 done
124+
125+
===Final messages===
126+
127+
{
128+
"content": "Can you generate a random number between 0 and 100?",
129+
"role": "user"
130+
}
131+
{
132+
"id": "...",
133+
"content": [
134+
{
135+
"annotations": [],
136+
"text": "Sure! Here's a random number between 0 and 100: **42**.",
137+
"type": "output_text"
138+
}
139+
],
140+
"role": "assistant",
141+
"status": "completed",
142+
"type": "message"
143+
}
144+
{
145+
"content": "I live in New York City. Whats the population of the city?",
146+
"role": "user"
147+
}
148+
{
149+
"id": "...",
150+
"content": [
151+
{
152+
"annotations": [],
153+
"text": "As of the most recent estimates, the population of New York City is approximately 8.6 million people. However, this number is constantly changing due to various factors such as migration and birth rates. For the latest and most accurate information, it's always a good idea to check the official data from sources like the U.S. Census Bureau.",
154+
"type": "output_text"
155+
}
156+
],
157+
"role": "assistant",
158+
"status": "completed",
159+
"type": "message"
160+
}
161+
{
162+
"content": "Por favor habla en espa\u00f1ol. \u00bfCu\u00e1l es mi nombre y d\u00f3nde vivo?",
163+
"role": "user"
164+
}
165+
{
166+
"id": "...",
167+
"content": [
168+
{
169+
"annotations": [],
170+
"text": "No tengo acceso a esa informaci\u00f3n personal, solo s\u00e9 lo que me has contado: vives en Nueva York.",
171+
"type": "output_text"
172+
}
173+
],
174+
"role": "assistant",
175+
"status": "completed",
176+
"type": "message"
177+
}
178+
"""
179+
180+
return result.final_output
181+
182+
183+
if __name__ == "__main__":
184+
main()

samples-v2/openai_agents/test_orchestrators.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"agent_lifecycle_example",
1818
"dynamic_system_prompt",
1919
"hello_world",
20+
"message_filter",
2021
"lifecycle_example",
2122
"local_image",
2223
"non_strict_output_type",

0 commit comments

Comments
 (0)