Skip to content

Commit af76c36

Browse files
Clarify shallow-copy behavior of tools and handoffs in Agent.clone() (#1296)
1 parent 1f75464 commit af76c36

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/agents/agent.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,17 @@ class Agent(AgentBase, Generic[TContext]):
222222
to True. This ensures that the agent doesn't enter an infinite loop of tool usage."""
223223

224224
def clone(self, **kwargs: Any) -> Agent[TContext]:
225-
"""Make a copy of the agent, with the given arguments changed. For example, you could do:
226-
```
227-
new_agent = agent.clone(instructions="New instructions")
228-
```
225+
"""Make a copy of the agent, with the given arguments changed.
226+
Notes:
227+
- Uses `dataclasses.replace`, which performs a **shallow copy**.
228+
- Mutable attributes like `tools` and `handoffs` are shallow-copied:
229+
new list objects are created only if overridden, but their contents
230+
(tool functions and handoff objects) are shared with the original.
231+
- To modify these independently, pass new lists when calling `clone()`.
232+
Example:
233+
```python
234+
new_agent = agent.clone(instructions="New instructions")
235+
```
229236
"""
230237
return dataclasses.replace(self, **kwargs)
231238

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from agents import Agent, function_tool, handoff
2+
3+
4+
@function_tool
5+
def greet(name: str) -> str:
6+
return f"Hello, {name}!"
7+
8+
def test_agent_clone_shallow_copy():
9+
"""Test that clone creates shallow copy with tools.copy() workaround"""
10+
target_agent = Agent(name="Target")
11+
original = Agent(
12+
name="Original",
13+
instructions="Testing clone shallow copy",
14+
tools=[greet],
15+
handoffs=[handoff(target_agent)],
16+
)
17+
18+
cloned = original.clone(
19+
name="Cloned",
20+
tools=original.tools.copy(),
21+
handoffs=original.handoffs.copy()
22+
)
23+
24+
# Basic assertions
25+
assert cloned is not original
26+
assert cloned.name == "Cloned"
27+
assert cloned.instructions == original.instructions
28+
29+
# Shallow copy assertions
30+
assert cloned.tools is not original.tools, "Tools should be different list"
31+
assert cloned.tools[0] is original.tools[0], "Tool objects should be same instance"
32+
assert cloned.handoffs is not original.handoffs, "Handoffs should be different list"
33+
assert cloned.handoffs[0] is original.handoffs[0], "Handoff objects should be same instance"

0 commit comments

Comments
 (0)