Build powerful AI agents that work across any LLM provider
Installation • Quick Start • Features • Examples • Docs • Contributing
Universal Agent SDK is a provider-agnostic Python framework for building LLM-powered agents. Write your agent logic once and run it on Claude, OpenAI, Azure OpenAI, Gemini, or any other provider—with zero code changes.
from universal_agent_sdk import query, AgentOptions
# Works with any provider - just change the config
options = AgentOptions(provider="openai", model="gpt-4o")
async for message in query("Explain quantum computing", options):
print(message)- 🔄 Provider Agnostic - Switch between Claude, GPT-4, Gemini with one line
- 🛠️ Batteries Included - Built-in tools for file ops, web search, shell commands
- 📦 Preset Configs - Load agent configurations from YAML/JSON files
- 🎣 Hooks System - Intercept and modify behavior at any point
- 🧠 Memory System - Conversation and persistent memory out of the box
- 🔒 Type Safe - Full type hints and dataclass configuration
pip install universal-agent-sdkWith specific providers:
pip install universal-agent-sdk[openai] # OpenAI/Azure
pip install universal-agent-sdk[google] # Gemini
pip install universal-agent-sdk[all] # All providersDevelopment installation:
git clone https://github.com/your-org/universal-agent-sdk-python.git
cd universal-agent-sdk-python
pip install -e ".[dev]"cp .env.sample .env
# Edit .env with your API keysimport asyncio
from universal_agent_sdk import query, AgentOptions
async def main():
options = AgentOptions(
provider="claude",
model="claude-sonnet-4-20250514",
)
async for message in query("What is the capital of France?", options):
print(message)
asyncio.run(main())import asyncio
from universal_agent_sdk import UniversalAgentClient, AgentOptions
async def main():
options = AgentOptions(
provider="openai",
model="gpt-4o",
system_prompt="You are a helpful coding assistant.",
)
async with UniversalAgentClient(options) as client:
# First message
await client.send("Write a Python function to reverse a string")
async for msg in client.receive():
print(msg)
# Follow-up (context is maintained)
await client.send("Now add type hints to it")
async for msg in client.receive():
print(msg)
asyncio.run(main())# List available presets
uv run python examples/programmatic/showcase/preset_loader.py --list
# Run with a preset
uv run python examples/programmatic/showcase/preset_loader.py --preset virtual-assistantSwitch providers with a single config change:
# Claude (Anthropic)
options = AgentOptions(provider="claude", model="claude-sonnet-4-20250514")
# OpenAI
options = AgentOptions(provider="openai", model="gpt-4o")
# Azure OpenAI
options = AgentOptions(
provider="azure_openai",
model="gpt-4o",
provider_config={
"endpoint": "https://your-resource.openai.azure.com",
"deployment_name": "your-deployment",
},
)
# Google Gemini
options = AgentOptions(provider="gemini", model="gemini-pro")Ready-to-use tools for common operations:
| Tool | Description |
|---|---|
ReadTool |
Read file contents with line numbers |
WriteTool |
Create or overwrite files |
EditTool |
Edit files using string replacement |
BashTool |
Execute shell commands |
GlobTool |
Find files by pattern matching |
GrepTool |
Search file contents with regex |
WebSearchTool |
Search the web via DuckDuckGo |
WebFetchTool |
Fetch and extract web page content |
DateTimeTool |
Get current date and time |
NotebookEditTool |
Edit Jupyter notebooks |
from universal_agent_sdk import AgentOptions
from universal_agent_sdk.tools import ReadTool, BashTool, WebSearchTool
options = AgentOptions(
provider="claude",
tools=[
ReadTool().to_tool_definition(),
BashTool().to_tool_definition(),
WebSearchTool().to_tool_definition(),
],
)Create tools with the simple @tool decorator:
from universal_agent_sdk import tool, query, AgentOptions
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city.
Args:
city: The city name (e.g., "London", "Tokyo")
"""
# Your implementation here
return f"Weather in {city}: Sunny, 72°F"
@tool
async def fetch_stock_price(symbol: str) -> str:
"""Fetch the current stock price.
Args:
symbol: Stock ticker symbol (e.g., "AAPL")
"""
# Async tools are supported!
return f"{symbol}: $150.00"
options = AgentOptions(
tools=[get_weather.definition, fetch_stock_price.definition],
)Define agent configurations in YAML:
# presets/research-agent.yaml
id: research-agent
name: Research Agent
description: Web research specialist
provider: claude
model: claude-sonnet-4-20250514
system_prompt: |
You are a research assistant specialized in finding
and analyzing information from web sources.
allowed_tools:
- WebSearch
- WebFetch
- Read
- Write
permission_mode: acceptEdits
max_turns: 50Load and use:
from universal_agent_sdk import load_preset, preset_to_options_with_tools
preset = load_preset("presets/research-agent.yaml")
options = preset_to_options_with_tools(preset) # Auto-loads tools!Intercept and modify agent behavior:
from universal_agent_sdk import AgentOptions, HookMatcher
async def log_tool_use(input_data, tool_use_id, context):
print(f"Tool called: {input_data['tool_name']}")
return {} # Continue execution
async def approve_dangerous_tools(input_data, tool_use_id, context):
if input_data["tool_name"] == "Bash":
# Could prompt user for approval here
return {"hookSpecificOutput": {"permissionDecision": "allow"}}
return {}
options = AgentOptions(
hooks={
"PreToolUse": [
HookMatcher(hooks=[log_tool_use]),
HookMatcher(matcher="Bash", hooks=[approve_dangerous_tools]),
],
},
)from universal_agent_sdk import AgentOptions
from universal_agent_sdk.memory import ConversationMemory, PersistentMemory
# In-memory conversation history
options = AgentOptions(
memory_enabled=True,
memory_type="conversation",
)
# Persistent memory with file storage
options = AgentOptions(
memory_enabled=True,
memory_type="persistent",
memory_config={"storage_path": "./memory"},
)The examples/ directory is organized for easy navigation:
examples/
├── programmatic/ # Direct SDK usage
│ ├── quickstart/ # Getting started
│ │ ├── 01_basic_query.py
│ │ ├── 02_streaming.py
│ │ ├── 03_options_demo.py
│ │ ├── 04_interactive_chat.py
│ │ └── 05_streaming_modes.py
│ ├── tools/ # Tool examples
│ ├── memory/ # Memory system
│ ├── skills/ # Skills framework
│ ├── hooks/ # Hook system
│ ├── agents/ # Agent patterns
│ ├── providers/ # Multi-provider
│ ├── advanced/ # Advanced features
│ ├── presets/ # YAML configurations
│ └── showcase/ # Full demos
│ ├── ultimate_assistant.py
│ ├── preset_loader.py
│ └── coding_agent.py
│
├── cli-tool/ # Claude Code-like CLI (coming soon)
├── vscode-extension/ # Copilot-like extension (coming soon)
├── desktop-ide/ # Cursor-like IDE (coming soon)
└── web-backend/ # FastAPI/Streamlit backend (coming soon)
# Basic query
uv run python examples/programmatic/quickstart/01_basic_query.py
# Interactive chat with presets
uv run python examples/programmatic/showcase/preset_loader.py --preset virtual-assistant
# Full-featured assistant
uv run python examples/programmatic/showcase/ultimate_assistant.py| Document | Description |
|---|---|
| Getting Started | Installation and first steps |
| Configuration | Provider setup and options |
| Core Components | Client, query, messages |
| Tools | Built-in and custom tools |
| Skills | Reusable agent components |
| Hooks | Behavior modification |
| Agents | Agent patterns and sub-agents |
| Memory | Conversation and persistence |
| API Reference | Complete API documentation |
Copy .env.sample to .env and configure:
# Required: At least one provider API key
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
# Optional: Azure, Google, AWS
AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_ENDPOINT=https://...
GOOGLE_API_KEY=...AgentOptions(
# Provider
provider="claude", # claude, openai, azure_openai, gemini
model="claude-sonnet-4-20250514",
# Prompts
system_prompt="You are helpful.",
# Tools
tools=[...], # List of ToolDefinition
tool_choice="auto", # auto, required, none
# Behavior
max_tokens=4096,
temperature=0.7,
max_turns=10,
# Memory
memory_enabled=False,
memory_type="conversation",
# Streaming
stream=True,
# Hooks
hooks={...},
)# Clone and install
git clone https://github.com/your-org/universal-agent-sdk-python.git
cd universal-agent-sdk-python
uv sync --all-extras
# Run linting
uv run ruff check src/ tests/
uv run ruff format src/ tests/
# Type checking
uv run mypy src/
# Run tests
uv run pytest tests/ -vWe welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by the Universal Agent SDK team