Skip to content

Clarify shallow-copy behavior of tools and handoffs in Agent.clone() #1296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Aug 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
00d3faf
Clarify shallow-copy behavior of tools and handoffs in Agent.clone()
abdul-kabir-jawed Jul 29, 2025
5a8a747
fix: remove trailing whitespace in Agent.clone docstring
abdul-kabir-jawed Jul 30, 2025
f1aced5
fix: remove trailing whitespace in Agent.clone docstring
abdul-kabir-jawed Jul 30, 2025
4656939
Merge branch 'main' into docs/agent-clone-shallow-copy
abdul-kabir-jawed Jul 30, 2025
b01105c
Your message describing the change
abdul-kabir-jawed Jul 30, 2025
89c4183
Update agent.py
abdul-kabir-jawed Jul 30, 2025
eb69161
fix(agent.py): remove trailing whitespace in clone method docstring
abdul-kabir-jawed Jul 30, 2025
10d167b
fix(agent.py): remove trailing whitespace in clone method docstring
abdul-kabir-jawed Jul 30, 2025
3743e3f
Merge branch 'main' into docs/agent-clone-shallow-copy
abdul-kabir-jawed Jul 30, 2025
edefa11
Delete uv.lock
abdul-kabir-jawed Jul 30, 2025
8716119
Create uv.lock
abdul-kabir-jawed Jul 30, 2025
61914a2
Update pyproject.toml
abdul-kabir-jawed Jul 30, 2025
236877d
Update test_agent_clone_shallow_copy.py
abdul-kabir-jawed Jul 31, 2025
fd071ee
Merge branch 'main' into docs/agent-clone-shallow-copy
abdul-kabir-jawed Jul 31, 2025
88647d0
Update test_agent_clone_shallow_copy.py
abdul-kabir-jawed Aug 1, 2025
fb9a13c
Merge branch 'main' into docs/agent-clone-shallow-copy
abdul-kabir-jawed Aug 1, 2025
055dd51
Update test_agent_clone_shallow_copy.py
abdul-kabir-jawed Aug 1, 2025
9b236ed
Merge branch 'main' into docs/agent-clone-shallow-copy
abdul-kabir-jawed Aug 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,17 @@ class Agent(AgentBase, Generic[TContext]):
to True. This ensures that the agent doesn't enter an infinite loop of tool usage."""

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

Expand Down
33 changes: 33 additions & 0 deletions tests/test_agent_clone_shallow_copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from agents import Agent, function_tool, handoff


@function_tool
def greet(name: str) -> str:
return f"Hello, {name}!"

def test_agent_clone_shallow_copy():
"""Test that clone creates shallow copy with tools.copy() workaround"""
target_agent = Agent(name="Target")
original = Agent(
name="Original",
instructions="Testing clone shallow copy",
tools=[greet],
handoffs=[handoff(target_agent)],
)

cloned = original.clone(
name="Cloned",
tools=original.tools.copy(),
handoffs=original.handoffs.copy()
)

# Basic assertions
assert cloned is not original
assert cloned.name == "Cloned"
assert cloned.instructions == original.instructions

# Shallow copy assertions
assert cloned.tools is not original.tools, "Tools should be different list"
assert cloned.tools[0] is original.tools[0], "Tool objects should be same instance"
assert cloned.handoffs is not original.handoffs, "Handoffs should be different list"
assert cloned.handoffs[0] is original.handoffs[0], "Handoff objects should be same instance"