diff --git a/src/agents/agent.py b/src/agents/agent.py index 72d3e03265..14333e0104 100644 --- a/src/agents/agent.py +++ b/src/agents/agent.py @@ -560,6 +560,16 @@ def clone(self, **kwargs: Any) -> Agent[TContext]: - To give the clone a list that no other agent holds, pass a new one, for example `agent.clone(tools=[*agent.tools, extra_tool])`. The entries copied into it remain the same objects the original agent holds. + - The same applies to the mutable attributes that are not lists, `model_settings` and + `mcp_config`. An omitted one arrives as the original agent's own object, so + `cloned.model_settings.temperature = 0.9` also changes the original. Pass a + replacement to keep them separate, for example + `agent.clone(model_settings=dataclasses.replace(agent.model_settings, + temperature=0.9))`. + - Overriding `model` alone does not give the clone its own `model_settings`. Fresh + settings are substituted only when the current ones still match the implicit + defaults for the current model, so an agent carrying any explicit setting keeps + sharing that object across `agent.clone(model=...)`. Example: ```python new_agent = agent.clone(instructions="New instructions") diff --git a/tests/test_agent_clone_shallow_copy.py b/tests/test_agent_clone_shallow_copy.py index 79559898b2..52683be9e7 100644 --- a/tests/test_agent_clone_shallow_copy.py +++ b/tests/test_agent_clone_shallow_copy.py @@ -1,4 +1,4 @@ -from agents import Agent, function_tool, handoff +from agents import Agent, ModelSettings, function_tool, handoff @function_tool @@ -79,3 +79,32 @@ def test_agent_clone_shared_list_mutation_affects_both_agents(): assert original.tools == cloned.tools assert len(original.tools) == 2 + + +def test_agent_clone_shares_non_list_mutable_attributes(): + """`model_settings` and `mcp_config` are shared too, which the list wording does not cover.""" + agent = Agent( + name="Original", + model="gpt-4o", + model_settings=ModelSettings(temperature=0.1), + mcp_config={"convert_schemas_to_strict": True}, + ) + + cloned = agent.clone(instructions="Changed") + + assert cloned.model_settings is agent.model_settings + assert cloned.mcp_config is agent.mcp_config + + cloned.model_settings.temperature = 0.9 + cloned.mcp_config["convert_schemas_to_strict"] = False + assert agent.model_settings.temperature == 0.9 + assert agent.mcp_config["convert_schemas_to_strict"] is False + + +def test_agent_clone_with_only_model_override_keeps_shared_model_settings(): + """Overriding `model` alone does not detach explicit settings from the original.""" + agent = Agent(name="Original", model="gpt-4o", model_settings=ModelSettings(temperature=0.1)) + + cloned = agent.clone(model="gpt-4o-mini") + + assert cloned.model_settings is agent.model_settings