---
title: "Migration Guide: v0.x to v1.x"
description: "Guide for migrating from Agency Swarm v0.x to v1.x (OpenAI Agents SDK based)"
icon: "book"
---
Agency Swarm v1.x is a complete rewrite built on the OpenAI Agents SDK, bringing significant improvements and new capabilities.
## Installation
```bash
pip install "agency-swarm<1.0.0"
```
v0.x documentation remains available at the current site until v1.0 reaches general availability.
```bash
pip install agency-swarm
```
If you encounter issues, please create a GitHub issue with the **v1.x** label.
## What's New in v1.x
Full support for reasoning models
Web Search and Computer Use capabilities
Async-first architecture with direct conversation control
Simple `@function_tool` decorator replaces complex BaseTool classes
No more black-box Assistants API - full control over threads and runs
### New Capabilities
- **Web Search & Computer Use**: Native OpenAI Responses API integration
- **Latest Models**: Full support for o3, o4-mini, and future OpenAI models via Responses API
- **Third-Party Models**: Use any Chat Completions API-compatible provider
- **Direct Thread Control**: No more black-box Assistants API limitations
- **Full Conversation Persistence**: Complete history management (not just thread IDs)
- **Enhanced Validation**: `output_guardrails` and `input_guardrails` system
### Architectural Improvements
- **Orchestrator Pattern on New Foundation**: Agency Swarm's proven orchestrator-workers pattern now runs on the OpenAI Agents SDK foundation
- **Async-first**: Native async execution for better performance
- **Enhanced Communication**: Defined `communication_flows` for coordinated multi-agent execution
- **Better State Management**: Complete conversation history persistence
### Enhanced Developer Experience
- **Structured Outputs**: Native Pydantic model support for agent outputs via `output_type`
- **Modern Tool System**: `@function_tool` decorator replaces `BaseTool` classes for cleaner tool definitions
- **Better Validation**: `output_guardrails` and `input_guardrails` replace the old `response_validator` system
- **Real-time Streaming**: Improved streaming capabilities with async response handling
The migration from v0.x to v1.x represents a fundamental shift in how Agency Swarm operates:
### Execution Core
- **v0.x**: Used OpenAI Assistants API runs directly
- **v1.x**: Uses `agents.Runner` from OpenAI Agents SDK for more control
### State Management
- **v0.x**: Relied on Assistant/Thread objects managed by OpenAI
- **v1.x**: Uses `ThreadManager` and `MessageStore` managed via `RunHooks` and shared `MasterContext`
### Agent Definition
- **v0.x**: Custom `Agent` class with Assistants API integration
- **v1.x**: `agency_swarm.Agent` extends `agents.Agent`, incorporating tools, subagent registration, and file handling
### Conversation History Persistence
This is an important architectural difference between versions:
- **v0.x (Assistants API)**: Required thread callbacks for production to persist OpenAI Assistant/Thread IDs. OpenAI managed conversation history server-side.
- **v1.x (Agents SDK)**: Required thread callbacks for production to persist complete conversation histories locally. You manage the full conversation state.
**Key Changes:**
- **Callback Structure**: `threads_callbacks` dict → separate `load_threads_callback` and `save_threads_callback` parameters
- **Data Format**: Thread IDs only → Complete conversation histories
- **Callback Signatures**: Unchanged (both use no-parameter callbacks with closure)
## Step-by-Step Migration
### Agency Constructor
```python v0.x
def load_threads(chat_id):
return load_threads_from_db(chat_id) # Returns thread IDs
def save_threads(new_threads):
save_threads_to_db(new_threads) # Saves thread IDs
agency = Agency(
agency_chart=[agent1, [agent1, agent2]], # Will show warning
threads_callbacks={
'load': lambda: load_threads(chat_id),
'save': lambda new_threads: save_threads(new_threads)
}
)
```
```python v1.x
def load_threads(chat_id):
# Load the complete conversation history instead of just thread IDs
return load_conversation_history(chat_id)
def save_threads(thread_dict):
# Persist the full conversation histories
save_conversation_history(thread_dict)
agency = Agency(
entry_point_agent, # Positional argument
communication_flows=[(agent1, agent2)],
load_threads_callback=lambda: load_threads(chat_id),
save_threads_callback=lambda new_threads: save_threads(new_threads)
)
```
**Data Format Change:** Your callbacks now need to store complete conversation histories instead of just thread IDs. Refer to [examples/custom_persistence.py](https://github.com/VRSEN/agency-swarm/blob/main/examples/custom_persistence.py) to see the example implementation.
### Agent Configuration
```python v0.x
agent = Agent(
name="MyAgent",
temperature=0.7,
max_completion_tokens=1000,
response_validator=my_validator
)
```
```python v1.x
agent = Agent(
name="MyAgent",
model="gpt-4.1",
model_settings=ModelSettings(
temperature=0.7,
max_tokens=1000,
),
output_guardrails=[my_guardrail]
)
```
### Simple Tool Conversion
This step is optional. Agency Swarm will keep maintaining the BaseTool approach for tool definition as well.
```python v0.x
class ProcessData(BaseTool):
"""Processes input data."""
input_data: str = Field(..., description="Data to process")
def run(self):
return f"Processed: {self.input_data}"
```
```python v1.x
@function_tool
def process_data(input_data: str) -> str:
"""Processes input data."""
return f"Processed: {input_data}"
```
### Tool with Context Access
```python v0.x
class AdvancedTool(BaseTool):
data: str = Field(..., description="Input data")
def run(self):
# Access shared state
shared_data = self._shared_state.get("key", "default")
return f"Result: {self.data} + {shared_data}"
```
```python v1.x
@function_tool
async def advanced_tool(ctx: RunContextWrapper[Any], data: str) -> str:
"""Advanced tool with context access."""
# Access shared state and other context
shared_data = ctx.context.get("key", "default")
return f"Result: {data} + {shared_data}"
```
### Response Validation
```python v0.x
class TestAgent(Agent):
def __init__(self):
super().__init__(
name="TestAgent",
description="..."
)
@override
def response_validator(self, message):
# User-defined validation function
if self.check_errors(message):
raise ValueError("Error processing message")
# Returns original message if no errors are raised
return message
```
```python v1.x
@output_guardrail
async def validate_response(
ctx: RunContextWrapper, agent: Agent, agent_response: str
) -> GuardrailFunctionOutput:
# User-defined validation logic
error_msg, tripwire_triggered = check_errors(agent_response)
return GuardrailFunctionOutput(
output_info=error_msg,
tripwire_triggered=tripwire_triggered,
)
agent = Agent(output_guardrails=[validate_response])
```
### Structured Outputs
```python v0.x
result = agency.get_completion(
"Analyze this data",
response_format={"type": "json_schema", "json_schema": {...}}
)
```
```python v1.x
class AnalysisResult(BaseModel):
status: str
findings: str
agent = Agent(output_type=AnalysisResult)
result = await agency.get_response("Analyze this data")
# result.final_output is now a typed AnalysisResult object
```
### Getting Agency Response
```python v0.x
# Removed in v1.x
result = agency.get_completion("Hello")
stream = agency.get_completion_stream("Hello")
```
```python v1.x
# Async (recommended)
import asyncio
async def main():
result = await agency.get_response("Hello")
print(result.final_output)
# Streaming (async only)
async def stream_example():
async for chunk in agency.get_response_stream("Hello"):
print(chunk)
asyncio.run(main())
```
## Complete Migration Example
```python
from agency_swarm import Agency, Agent, BaseTool
from pydantic import Field
class DataProcessor(BaseTool):
"""Processes data."""
data: str = Field(..., description="Input data")
def run(self):
return f"Processed: {self.data}"
class Analyst(Agent):
def __init__(self):
super().__init__(
name="Analyst",
description="Analyzes data",
tools=[DataProcessor],
temperature=0.7
)
def response_validator(self, message):
if "error" in message.lower():
raise ValueError("Invalid response")
return message
agency = Agency(
agency_chart=[Analyst()],
shared_instructions="Be helpful and accurate."
)
result = agency.get_completion("Analyze sample data")
```
```python
from agency_swarm import (
Agency,
Agent,
function_tool,
ModelSettings,
output_guardrail,
GuardrailFunctionOutput,
)
from pydantic import BaseModel, Field
import asyncio
# Modern tool definition
@function_tool
def data_processor(data: str) -> str:
"""Processes data."""
return f"Processed: {data}"
# Structured output
class AnalysisResult(BaseModel):
status: str
findings: str
# Validation guardrail
@output_guardrail
async def validate_analysis(ctx, agent, response):
if "error" in response.lower():
return GuardrailFunctionOutput(
output_info="Invalid response detected",
tripwire_triggered=True
)
return GuardrailFunctionOutput(output_info="Valid response")
# Agent with modern configuration
analyst = Agent(
name="Analyst",
description="Analyzes data",
tools=[data_processor],
output_type=AnalysisResult,
output_guardrails=[validate_analysis],
model="gpt-4.1",
model_settings=ModelSettings(temperature=0.7),
)
agency = Agency(
analyst,
shared_instructions="Be helpful and accurate."
)
# Modern async usage
async def main():
result = await agency.get_response("Analyze sample data")
print(result.final_output) # Typed AnalysisResult object
asyncio.run(main())
```
## Reference Tables
### Agency Methods
| v0.x | Status | v1.x alternative |
|:----:|:------:|:----------------:|
| `get_completion()` | ❌ Removed | `get_response()` (async) |
| `get_completion_stream()` | ❌ Removed | `get_response_stream()` (async) |
| `agency_chart` | ❌ Removed | Positional args + `communication_flows` |
| `model` (global default) | ❌ Removed | Configure each `Agent` via `model` |
| `threads_callbacks` | ❌ Breaking change | `load_threads_callback` + `save_threads_callback` |
### Agent Parameters
| v0.x | Status | v1.x alternative |
|:----:|:------:|:----------------:|
| `temperature`, `top_p`, etc. | ❌ Removed | `model_settings=ModelSettings(...)` |
| `response_validator` | ❌ Removed | `output_guardrails`, `input_guardrails` |
| `response_format` | ❌ Removed | `output_type` |
| `examples` | ❌ Removed | Include in `instructions` or pass message history to `get_response` / `get_response_stream` |
### Tools
| v0.x | Status | v1.x alternative |
|:----:|:------:|:----------------:|
| `BaseTool` classes | ✅ Supported | `@function_tool` decorator (recommended) |
| `run()` method | ✅ Simplified | Direct function body implementation |
| `_shared_state` | ❌ Removed | `ctx.context` |
## Getting Help
Working v1.x examples with detailed comments
Report v1.x issues with the **v1.x** label
Official OpenAI Agents SDK documentation
Current production documentation