Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The [OpenAI Agents SDK](https://github.com/openai/openai-agents-python) enables
- **Handoffs**, which allow agents to delegate to other agents for specific tasks
- **Guardrails**, which enable the inputs to agents to be validated
- **Sessions**, which automatically maintains conversation history across agent runs
- **Tracing**, which lets you visualize and debug the flow of an agent's actions


In combination with Python, these primitives are powerful enough to express complex relationships between tools and agents, and allow you to build real-world applications without a steep learning curve. In addition, the SDK comes with built-in **tracing** that lets you visualize and debug your agentic flows, as well as evaluate them and even fine-tune models for your application.

Expand Down
12 changes: 7 additions & 5 deletions docs/running_agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ You can use the Agents SDK [Temporal](https://temporal.io/) integration to run d

The SDK raises exceptions in certain cases. The full list is in [`agents.exceptions`][]. As an overview:

- [`AgentsException`][agents.exceptions.AgentsException] is the base class for all exceptions raised in the SDK.
- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] is raised when the run exceeds the `max_turns` passed to the run methods.
- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError] is raised when the model produces invalid outputs, e.g. malformed JSON or using non-existent tools.
- [`UserError`][agents.exceptions.UserError] is raised when you (the person writing code using the SDK) make an error using the SDK.
- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered], [`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] is raised when a [guardrail](guardrails.md) is tripped.
- [`AgentsException`][agents.exceptions.AgentsException]: This is the base class for all exceptions raised within the SDK. It serves as a generic type from which all other specific exceptions are derived.
- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded]: This exception is raised when the agent's run exceeds the `max_turns` limit passed to the `Runner.run`, `Runner.run_sync`, or `Runner.run_streamed` methods. It indicates that the agent could not complete its task within the specified number of interaction turns.
- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError]: This exception occurs when the underlying model (LLM) produces unexpected or invalid outputs. This can include:
- Malformed JSON: When the model provides a malformed JSON structure for tool calls or in its direct output, especially if a specific `output_type` is defined.
- Unexpected tool-related failures: When the model fails to use tools in an expected manner
- [`UserError`][agents.exceptions.UserError]: This exception is raised when you (the person writing code using the SDK) make an error while using the SDK. This typically results from incorrect code implementation, invalid configuration, or misuse of the SDK's API.
- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered], [`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered]: This exception is raised when the conditions of an input guardrail or output guardrail are met, respectively. Input guardrails check incoming messages before processing, while output guardrails check the agent's final response before delivery.
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
35 changes: 35 additions & 0 deletions tests/test_agent_clone_shallow_copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

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"