Skip to content

Commit 931336a

Browse files
updated naming & example
1 parent 518914a commit 931336a

File tree

3 files changed

+61
-10
lines changed

3 files changed

+61
-10
lines changed

examples/basic/max_turns_resume.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from typing import Annotated
2+
3+
from agents import Agent, MaxTurnsExceeded, Runner, function_tool
4+
5+
6+
@function_tool
7+
def gather_facts(topic: Annotated[str, "The topic to investigate"]) -> str:
8+
"""Return placeholder research that simulates a tool lookup."""
9+
return (
10+
f"Key facts about {topic}: it moves through evaporation, condensation, "
11+
"precipitation, and collection."
12+
)
13+
14+
15+
def main():
16+
agent = Agent(
17+
name="Researcher",
18+
instructions=(
19+
"You must call the gather_facts tool before answering. "
20+
"Once you have the tool output, summarize it in your own words."
21+
),
22+
tools=[gather_facts],
23+
)
24+
25+
try:
26+
Runner.run_sync(
27+
agent,
28+
input="Give me the main stages of the water cycle.",
29+
max_turns=1,
30+
)
31+
except MaxTurnsExceeded as exc:
32+
print("Reached the max turn limit. Asking the agent to finalize without tools...\n")
33+
result = exc.resume_sync(
34+
"Finish the answer using the gathered information without calling tools again."
35+
)
36+
print(result.final_output)
37+
# The water cycle proceeds through evaporation, condensation, precipitation, and collection.
38+
39+
40+
if __name__ == "__main__":
41+
main()

src/agents/exceptions.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,13 @@ def __init__(self, message: str):
6161
self.message = message
6262
super().__init__(message)
6363

64-
def resume(self, prompt: Optional[str] = _DEFAULT_RESUME_PROMPT) -> RunResult:
65-
"""Resume the failed run synchronously with a final, tool-free turn.
64+
async def resume(self, prompt: Optional[str] = _DEFAULT_RESUME_PROMPT) -> RunResult:
65+
"""Resume the failed run asynchronously with a final, tool-free turn.
66+
67+
Note:
68+
This helper does not automatically reuse the original session object.
69+
If you need the resumed turn to be persisted in the session,
70+
run the follow-up turn manually with that information.
6671
6772
Args:
6873
prompt: Optional user instruction to append before rerunning the final turn.
@@ -74,16 +79,21 @@ def resume(self, prompt: Optional[str] = _DEFAULT_RESUME_PROMPT) -> RunResult:
7479

7580
from .run import Runner
7681

77-
return Runner.run_sync(
82+
return await Runner.run(
7883
starting_agent=run_data.last_agent,
7984
input=inputs,
8085
context=run_data.context_wrapper.context,
8186
max_turns=1,
8287
run_config=run_config,
8388
)
8489

85-
async def resume_async(self, prompt: Optional[str] = _DEFAULT_RESUME_PROMPT) -> RunResult:
86-
"""Resume the failed run asynchronously with a final, tool-free turn.
90+
def resume_sync(self, prompt: Optional[str] = _DEFAULT_RESUME_PROMPT) -> RunResult:
91+
"""Resume the failed run synchronously with a final, tool-free turn.
92+
93+
Note:
94+
This helper does not automatically reuse the original session object.
95+
If you need the resumed turn to be persisted in the session,
96+
run the follow-up turn manually with that information.
8797
8898
Args:
8999
prompt: Optional user instruction to append before rerunning the final turn.
@@ -95,7 +105,7 @@ async def resume_async(self, prompt: Optional[str] = _DEFAULT_RESUME_PROMPT) ->
95105

96106
from .run import Runner
97107

98-
return await Runner.run(
108+
return Runner.run_sync(
99109
starting_agent=run_data.last_agent,
100110
input=inputs,
101111
context=run_data.context_wrapper.context,

tests/test_max_turns.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ async def test_streamed_max_turns():
7676

7777

7878
@pytest.mark.asyncio
79-
async def test_max_turns_resume_async_runs_final_turn():
79+
async def test_max_turns_resume_runs_final_turn():
8080
model = FakeModel()
8181
agent = Agent(
8282
name="test_1",
@@ -98,7 +98,7 @@ async def test_max_turns_resume_async_runs_final_turn():
9898
with pytest.raises(MaxTurnsExceeded) as exc_info:
9999
await Runner.run(agent, input="user_message", max_turns=2)
100100

101-
result = await exc_info.value.resume_async("Finish without tools.")
101+
result = await exc_info.value.resume("Finish without tools.")
102102

103103
assert result.final_output == final_answer
104104
resume_input = model.last_turn_args["input"]
@@ -130,7 +130,7 @@ def test_max_turns_resume_sync_uses_default_prompt():
130130
with pytest.raises(MaxTurnsExceeded) as exc_info:
131131
Runner.run_sync(agent, input="user_message", max_turns=2)
132132

133-
result = exc_info.value.resume()
133+
result = exc_info.value.resume_sync()
134134

135135
assert result.final_output == final_answer
136136
resume_input = model.last_turn_args["input"]
@@ -167,7 +167,7 @@ async def test_resume_preserves_run_config_settings():
167167
with pytest.raises(MaxTurnsExceeded) as exc_info:
168168
await Runner.run(agent, input="user_message", max_turns=2, run_config=run_config)
169169

170-
await exc_info.value.resume_async("Finish without tools.")
170+
await exc_info.value.resume("Finish without tools.")
171171

172172
final_settings = model.last_turn_args["model_settings"]
173173
assert final_settings.temperature == 0.25

0 commit comments

Comments
 (0)