A dynamic, plugin-based multi-agent system built on Microsoft's Agent Framework with automatic tool and agent discovery. Create powerful AI agents with just YAML configuration files - minimal code!
# 1️⃣ Manually create tools
from azure.ai.projects.agentic import FunctionTool
def weather_tool():
"""Hard-coded tool definition"""
pass
weather = FunctionTool(weather_tool, ...)
# 2️⃣ Manually register in __init__.py
from .weather import weather_tool
from .stock import stock_tool
# ... repeat for every tool
# 3️⃣ Hard-code agent configuration
agent = ChatAgent(
name="Weather Agent",
instructions="Long prompt...",
tools=[weather, forecast, ...] # Manual list
)
# 4️⃣ Edit Python for every change
# Want to add a tool? Edit 3+ files
# Want to change prompt? Edit Python
# Want new agent? Write more PythonPain Points:
|
# 1️⃣ Drop a tool file - auto-discovered!
# tools/weather/humidity.py
@tool(domain="weather", description="...")
def get_humidity(location: str) -> str:
return f"Humidity: 65%"
# Done! ✨ Automatically registered
# 2️⃣ Drop a YAML file - instant agent!
# agents/weather_agent.yaml
name: "Weather Assistant"
tool_domains: ["weather"]
instructions: |
You are a weather assistant...
# Done! ✨ Automatically created
# 3️⃣ Launch DevUI
python run_devui.py
# All agents & tools auto-discovered! 🚀Benefits:
|
| Metric | Before | After | Improvement |
|---|---|---|---|
| Lines of Code per Tool | 20-30 | 5-8 | 75% reduction |
| Files to Edit per Agent | 3-5 | 1 | 80% reduction |
| Time to Add Tool | 15-20 min | 2-3 min | 85% faster |
| Time to Add Agent | 30-45 min | 5 min | 90% faster |
| Manual Imports | Every tool | Zero | 100% automated |
| Configuration Changes | Edit Python | Edit YAML | Non-technical friendly |
Traditional Approach:
─────────────────────────────────────────────────────────────────
Create tool.py → Edit __init__.py → Import in agent.py →
Create agent class → Register agent → Test → Debug imports →
Restart → Test again
⏱️ Time: ~45 minutes per agent
This Framework:
─────────────────────────────────────────────────────────────────
Drop tool.py → Drop agent.yaml → Run DevUI
⏱️ Time: ~5 minutes per agent
🚀 10x faster development
- Zero-Code Tool Integration: Drop a Python file in
tools/domain/and it's automatically available - Decorator-Based Registration: Simple
@tooldecorator handles all registration - Domain Organization: Tools organized by business domain (weather, stock, email, calendar)
- Tag-Based Filtering: Fine-grained control over which tools each agent gets
- Hot-Reload Support: Modify tools without restarting the system
- YAML-Based Configuration: Define agents declaratively without writing Python
- Zero-Code Agent Creation: Drop a YAML file in
agents/and it's immediately available - Automatic Tool Attachment: Agents automatically discover and attach tools based on domains/tags
- No Manual Registration: No need to edit
__init__.pyor import statements
- Sequential Workflows: Chain agents in sequence for complex workflows
- Parallel Execution: Run multiple agents concurrently with fan-out/fan-in patterns
- Custom Aggregators: Combine parallel results with custom logic
- Multi-Provider LLM Support: Azure OpenAI, OpenRouter, and direct OpenAI with automatic fallback
- DevUI Integration: Built-in web interface for testing and debugging
- Comprehensive Logging: Detailed logs for tool discovery and agent creation
- Mock & Real APIs: Easy toggle between mock data and real API integrations
- Gmail Integration: Full OAuth2 support for real email operations
- OpenRouter Support: Access to 100+ LLM models through a single API
- Type Safety: Full type hints and annotations throughout
- Quick Start
- Installation
- Project Structure
- Core Concepts
- Creating Tools
- Creating Agents
- Running the System
- Examples
- Architecture
- Configuration
- Contributing
- License
- Python 3.11 or higher
- One of the following LLM providers:
- Azure OpenAI (with Azure CLI)
- OpenRouter API key (Get one here)
- Direct OpenAI API key
- Optional:
- Gmail account (for real email features)
- Google Cloud project (for Gmail API)
- Clone the repository
git clone https://github.com/yourusername/agentic-ms.git
cd agentic-ms- Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate- Install dependencies
pip install -r requirements.txt- Configure environment
# Copy example environment file
cp .env.example .env
# Edit with your API keys and configuration
nano .env # or use your preferred editorChoose your LLM provider (edit .env):
-
Option A: OpenRouter (Easiest for testing)
OPENROUTER_API_KEY=sk-or-v1-your-key-here OPENROUTER_MODEL=openai/gpt-4-turbo
-
Option B: Azure OpenAI
az login # Authenticate Azure CLIAZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com/ AZURE_OPENAI_DEPLOYMENT=gpt-4o
-
Option C: Direct OpenAI
OPENAI_API_KEY=sk-your-key-here OPENAI_MODEL=gpt-4-turbo-preview
- Optional: Enable Gmail Integration
See Setup Guide - Gmail Section for detailed instructions.
Quick setup:
USE_REAL_EMAIL_API=true
GMAIL_CREDENTIALS_FILE=credentials.json
GMAIL_USER_EMAIL=your.email@gmail.com- Run the DevUI
# Using bun (recommended)
bun run agent
# Or using Python directly
python run_devui.pyOpen http://localhost:8080 in your browser and start chatting with agents!
🚀 New to the project? Check out the Quick Start Guide (5 min setup!)
📚 For detailed setup instructions, see the Complete Setup Guide
agentic-ms/
├── agents/ # Agent YAML configurations
│ ├── agent_factory.py # Factory for creating agents from YAML
│ ├── __init__.py # Auto-discovery of all agents
│ ├── weather_agent.yaml # Weather assistant configuration
│ ├── stock_agent.yaml # Stock market assistant configuration
│ ├── email_agent.yaml # Email assistant configuration
│ ├── calendar_agent.yaml # Calendar assistant configuration
│ └── general_openrouter_agent.yaml # OpenRouter-powered agent (NEW)
│
├── tools/ # Tool library (auto-discovered)
│ ├── _decorators.py # @tool decorator for registration
│ ├── _registry.py # Central tool registry (singleton)
│ ├── _loader.py # Auto-discovery engine
│ ├── __init__.py # Package initialization
│ │
│ ├── weather/ # Weather domain tools
│ │ ├── current_weather.py
│ │ └── forecast.py
│ │
│ ├── stock/ # Stock market domain tools
│ │ ├── stock_price.py
│ │ ├── stock_analysis.py
│ │ └── stock_history.py
│ │
│ ├── email/ # Email domain tools
│ │ ├── send_email.py
│ │ ├── read_inbox.py
│ │ ├── search_emails.py
│ │ └── gmail_utils.py # Gmail API integration (NEW)
│ │
│ ├── calendar/ # Calendar domain tools
│ │ ├── create_event.py
│ │ ├── list_events.py
│ │ └── find_free_time.py
│ │
│ └── common/ # Shared utility tools
│
├── workflows/ # Workflow orchestrations
│ ├── financial_workflow.py # Sequential workflow example
│ └── reusable_workflows.py # Parallel workflow examples
│
├── docs/ # Documentation
│ ├── DYNAMIC_TOOL_ARCHITECTURE.md
│ ├── AGENT_WORKFLOW_ARCHITECTURE.md
│ ├── PARALLEL_EXECUTION_QUICKSTART.md
│ ├── SETUP_GUIDE.md # Complete setup guide (NEW)
│ └── EMAIL_AGENT_DEMO.md
│
├── demos/ # Demo scripts
│ ├── demo_parallel_execution.py
│ └── workflow_runner.py
│
├── run_devui.py # Launch DevUI with all agents
├── test_agent_factory.py # Test YAML-based agents
├── test_auto_discovery.py # Test automatic discovery
└── requirements.txt # Python dependencies
Tools are Python functions decorated with @tool that provide specific capabilities to agents.
Key Features:
- Automatic discovery via filesystem scanning
- Domain-based organization (weather, stock, email, etc.)
- Tag-based filtering for fine-grained control
- Mock vs real API support
Agents are AI assistants configured via YAML files that automatically discover and use tools.
Key Features:
- Declarative YAML configuration
- Automatic tool attachment based on domains/tags
- Editable prompts without code changes
- Azure OpenAI integration
Workflows orchestrate multiple agents to solve complex tasks.
Types:
- Sequential: Agents run one after another
- Parallel: Agents run concurrently (fan-out/fan-in)
- Custom: Build complex routing and conditional logic
Create a Python file in the appropriate domain folder:
# tools/weather/humidity.py
from typing import Annotated
from tools._decorators import tool
@tool(
domain="weather",
description="Get humidity levels for a location",
tags=["weather", "humidity", "conditions"],
mock=True, # Set to False when using real APIs
)
def get_humidity(
location: Annotated[str, "The location to check humidity for"]
) -> str:
"""Get humidity percentage for a given location.
Args:
location: City name or location string
Returns:
Formatted string with humidity information
"""
# Mock implementation
return f"Humidity in {location}: 65%"The tool is now:
- ✅ Automatically discovered at startup
- ✅ Registered in the tool registry
- ✅ Available to all agents with
tool_domains: ["weather"]
No code editing, imports, or registration needed!
@tool(
domain: str, # Required: Tool domain (weather, stock, email, etc.)
name: Optional[str], # Optional: Tool name (defaults to function name)
description: Optional[str], # Optional: Description (defaults to docstring)
tags: Optional[list], # Optional: Additional tags for filtering
mock: bool = False, # Optional: Is this a mock implementation?
requires_api_key: Optional[str], # Optional: API key environment variable
)Create a YAML file in the agents/ directory:
# agents/news_agent.yaml
name: "News Assistant"
description: "Provides latest news headlines and articles"
# Tool Discovery - automatically finds matching tools
tool_domains:
- news
tool_tags:
- news
- headlines
- articles
# Optional: Exclude specific tools
# exclude_tools:
# - news.experimental_feature
# Agent Instructions (the "prompt")
instructions: |
You are a news assistant. Provide latest news headlines
and articles when asked. Always cite your sources and
present information objectively.
When users ask about news:
1. Use the appropriate tool to fetch articles
2. Summarize key points clearly
3. Provide source attribution
# Model Configuration - Multi-Provider with Automatic Fallback
model:
# Provider list (will try in order until one succeeds)
providers:
- "openrouter" # Try OpenRouter first (easiest, no auth issues)
- "azure" # Fall back to Azure if available
- "openai" # Fall back to OpenAI if available
# Azure configuration (used if azure provider succeeds)
endpoint: "https://your-azure-openai.openai.azure.com/"
deployment: "gpt-4o"
credential_type: "azure_cli"
# OpenRouter/OpenAI config loaded from environment:
# OPENROUTER_API_KEY, OPENROUTER_MODEL, OPENAI_API_KEYIf the domain doesn't exist, create tools for it:
# tools/news/get_headlines.py
from tools._decorators import tool
@tool(domain="news", description="Get latest news headlines")
def get_headlines(category: str = "general") -> str:
"""Fetch latest news headlines."""
# Implementation here
return "Latest headlines..."python run_devui.pyThe news agent is now automatically:
- ✅ Discovered from the YAML file
- ✅ Created with matching tools attached
- ✅ Available in the DevUI
No Python code editing required!
Launch the development web interface:
python run_devui.pyFeatures:
- Chat with individual agents
- Test workflows
- View agent capabilities
- Debug tool calls
Use agents programmatically:
from agents import get_all_agents
import asyncio
async def main():
# Get all auto-discovered agents
agents = get_all_agents()
# Use weather agent
weather_agent = agents['weather_agent']
response = await weather_agent.run("What's the weather in Tokyo?")
print(response)
asyncio.run(main())Run the test suites:
# Test tool discovery
python -c "from tools import ToolRegistry; print(ToolRegistry().get_summary())"
# Test agent creation
python test_agent_factory.py
# Test automatic discovery
python test_auto_discovery.pyfrom agents import get_all_agents
import asyncio
async def main():
agents = get_all_agents()
weather_agent = agents['weather_agent']
response = await weather_agent.run(
"What's the weather forecast for Seattle this week?"
)
print(response)
asyncio.run(main())from agent_framework import SequentialBuilder
from agents import get_all_agents
agents = get_all_agents()
stock_agent = agents['stock_agent']
weather_agent = agents['weather_agent']
workflow = (
SequentialBuilder()
.add_agent(stock_agent)
.add_agent(weather_agent)
.build()
)
# Execute: stock analysis → weather check
result = await workflow.run("Analyze AAPL and check weather in Cupertino")from agent_framework import ConcurrentBuilder
from agents import get_all_agents
agents = get_all_agents()
workflow = (
ConcurrentBuilder()
.participants([agents['stock_agent'], agents['weather_agent']])
.build()
)
# Both agents run simultaneously
result = await workflow.run("Get AAPL price and Seattle weather")# tools/news/search_articles.py
from typing import Annotated
from tools._decorators import tool
@tool(
domain="news",
description="Search news articles by keyword",
tags=["news", "search", "articles"],
mock=True
)
def search_articles(
query: Annotated[str, "Search query"],
days: Annotated[int, "Days to look back"] = 7
) -> str:
"""Search for news articles matching the query."""
return f"Found 10 articles about '{query}' from last {days} days"┌─────────────────────────────────────────────────────────────────────┐
│ MS-AGENTIC FRAMEWORK ACCELERATOR │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ AGENT LAYER (YAML) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Weather Agent│ │Calendar Agent│ │ Stock Agent │ │ │
│ │ │ .yaml │ │ .yaml │ │ .yaml │ │ │
│ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │
│ └─────────┼──────────────────┼──────────────────┼──────────────┘ │
│ │ │ │ │
│ ┌─────────▼──────────────────▼──────────────────▼──────────────┐ │
│ │ AGENT FACTORY (Dynamic Discovery) │ │
│ │ • YAML Parser • Tool Discovery Integration │ │
│ │ • Chat Client • Multi-Provider Fallback │ │
│ │ • Context Injector • Azure/OpenRouter/OpenAI Support │ │
│ └─────────┬────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────▼────────────────────────────────────────────────────┐ │
│ │ TOOL REGISTRY & DISCOVERY ENGINE │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Automatic Tool Discovery │ │ │
│ │ │ • Recursive directory scanning │ │ │
│ │ │ • @tool decorator detection │ │ │
│ │ │ • Metadata extraction │ │ │
│ │ │ • Dynamic registration │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Tool Registry (Singleton) │ │ │
│ │ │ • Domain filtering (weather, calendar, stock) │ │ │
│ │ │ • Tag filtering (forecast, event, price) │ │ │
│ │ │ • Metadata storage (docs, params, types) │ │ │
│ │ │ • Hot-reload support │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼───────────────────────────────────┐ │
│ │ TOOL DOMAINS (4 Active Domains) │ │
│ │ │ │
│ │ ┌────────────┐ ┌────────────┐ ┌─────────┐ ┌──────────┐ │ │
│ │ │ WEATHER │ │ CALENDAR │ │ STOCK │ │ EMAIL │ │ │
│ │ │ Domain │ │ Domain │ │ Domain │ │ Domain │ │ │
│ │ ├────────────┤ ├────────────┤ ├─────────┤ ├──────────┤ │ │
│ │ │ current_ │ │ create_ │ │ stock_ │ │ send_ │ │ │
│ │ │ weather │ │ event │ │ price │ │ email │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ forecast │ │ list_ │ │ stock_ │ │ read_ │ │ │
│ │ │ │ │ events │ │ analysis│ │ inbox │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ │ delete_ │ │ stock_ │ │ search_ │ │ │
│ │ │ │ │ event │ │ history │ │ emails │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ │ find_free_ │ │ │ │ organize │ │ │
│ │ │ │ │ time │ │ │ │ _email │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ (2 tools) │ │ (4 tools) │ │(3 tools)│ │ (4 tools)│ │ │
│ │ └────────────┘ └────────────┘ └─────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼───────────────────────────────────┐ │
│ │ DEVUI & ORCHESTRATION │ │
│ │ • Web-based UI for agent interaction │ │
│ │ • Real-time tool discovery display │ │
│ │ • Auto-startup agent loading │ │
│ │ • Sequential & parallel workflow execution │ │
│ │ • Live execution monitoring │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ START: run_devui.py │
└────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ ToolLoader.discover_tools() │
│ • Scans tools/ directory │
│ • Recursively walks subdirectories │
│ • Finds all .py files │
└─────────────────────────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ tools/ │ │ tools/ │ │ tools/ │
│ weather/ │ │ calendar/ │ │ stock/ │
│ │ │ │ │ │
│ current_ │ │ create_ │ │ stock_ │
│ weather.py │ │ event.py │ │ price.py │
│ │ │ │ │ │
│ forecast.py │ │ list_ │ │ stock_ │
│ │ │ events.py │ │ analysis.py │
│ │ │ │ │ │
│ │ │ delete_ │ │ stock_ │
│ │ │ event.py │ │ history.py │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└─────────────┼─────────────┘
│
▼
┌─────────────────────────────────────┐
│ For each file: │
│ • Import module dynamically │
│ • Find @tool decorated functions │
│ • Extract metadata │
│ • Register in ToolRegistry │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ ToolRegistry (Singleton) │
│ _tools = { │
│ "weather.current_weather": {...},│
│ "calendar.create_event": {...}, │
│ "stock.stock_price": {...}, │
│ ... │
│ } │
│ │
│ ✓ 11+ tools registered │
│ ✓ 4 domains active │
└─────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ AgentFactory.discover_all_agents() │
│ • Scans agents/ directory for *.yaml files │
└────────────────────────────────────────────────────────────────┘
│
┌────────────────────┴────────────────────┐
│ │
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ weather_agent.yaml │ │ stock_agent.yaml │
│ ┌──────────────────────┐│ │ ┌──────────────────────┐│
│ │ 1. Load YAML config ││ │ │ 1. Load YAML config ││
│ │ ││ │ │ ││
│ │ 2. Parse domains: ││ │ │ 2. Parse domains: ││
│ │ [weather] ││ │ │ [stock, weather] ││
│ │ ││ │ │ ││
│ │ 3. Query registry: ││ │ │ 3. Query registry: ││
│ │ get_tools_by_ ││ │ │ get_tools_by_ ││
│ │ domain("weather") ││ │ │ domain("stock") ││
│ │ ││ │ │ ││
│ │ 4. Results: ││ │ │ 4. Results: ││
│ │ [current_weather, ││ │ │ [stock_price, ││
│ │ forecast] ││ │ │ stock_analysis, ││
│ │ ││ │ │ stock_history] + ││
│ │ 5. Build client: ││ │ │ [current_weather] ││
│ │ Try providers: ││ │ │ ││
│ │ - OpenRouter ✓ ││ │ │ 5. Build client: ││
│ │ ││ │ │ Try providers: ││
│ │ 6. Inject context: ││ │ │ - OpenRouter ✓ ││
│ │ Add tool docs to ││ │ │ ││
│ │ instructions ││ │ │ 6. Inject context ││
│ │ ││ │ │ ││
│ │ 7. Create ChatAgent ││ │ │ 7. Create ChatAgent ││
│ │ ✓ Ready! ││ │ │ ✓ Ready! ││
│ └──────────────────────┘│ │ └──────────────────────┘│
└──────────────────────────┘ └──────────────────────────┘
│
▼
┌──────────────────────────────────┐
│ All agents loaded: │
│ { │
│ 'weather_agent': <ChatAgent>, │
│ 'calendar_agent': <ChatAgent>, │
│ 'stock_agent': <ChatAgent>, │
│ 'email_agent': <ChatAgent> │
│ } │
└──────────────────────────────────┘
│
▼
┌──────────────────────────────────┐
│ StartupLogger displays: │
│ • Tools discovered by domain │
│ • Agents created │
│ • Agent → Tool mappings │
│ • Model provider info │
└──────────────────────────────────┘
│
▼
┌──────────────────────────────────┐
│ DevUI Server Launch │
│ serve(entities=agents) │
│ → http://localhost:8080 │
└──────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Agent YAML Configuration │
│ ┌────────────────────────────────────────────────────┐ │
│ │ model: │ │
│ │ providers: ← Try in order │ │
│ │ - "openrouter" ← 1st: Easy, no auth │ │
│ │ - "azure" ← 2nd: Enterprise │ │
│ │ - "openai" ← 3rd: Direct API │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│OpenRouter│ │ Azure │ │ OpenAI │
│ Client │ │ OAI Client│ │ Client │
└─────┬────┘ └─────┬────┘ └─────┬────┘
│ │ │
│ Try connect │ │
Success? ─┼─ YES ──┐ │ │
│ │ │ │
│ NO ───┼──────┼─ Try Azure │
│ │ │ │
│ │ Success? ───┐ │
│ │ │ │ │
│ │ NO ─┼──────┼── Try OpenAI
│ │ │ │ │
│ │ │ Success? ───┤
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────────────────────────────────┐
│ Return working client to AgentFactory │
│ • Zero config changes needed │
│ • Automatic failover │
│ • Production-ready reliability │
└──────────────────────────────────────────┘
User launches application
│
▼
run_devui.py
│
├─► Load environment (.env)
│
├─► Import agents package
│ │
│ └─► agents/__init__.py
│ │
│ ├─► AgentFactory()
│ │
│ └─► discover_all_agents()
│ │
│ ├─► Scan agents/*.yaml
│ │
│ └─► For each YAML:
│ │
│ ├─► Parse config
│ │
│ ├─► Query ToolRegistry
│ │ └─► get_tools_by_domain()
│ │
│ ├─► Build chat client
│ │ └─► Try providers
│ │
│ ├─► Inject tool context
│ │ └─► Enhance instructions
│ │
│ └─► Create ChatAgent
│
├─► Get discovery data
│ └─► {agents, tools_by_domain, mappings}
│
├─► Print startup summary
│ └─► Beautiful CLI output
│
└─► Start DevUI server
└─► serve() → http://localhost:8080
│
└─► Browser auto-opens
│
└─► User interacts with agents
│
└─► Agents use tools dynamically
The ToolRegistry maintains a central registry of all discovered tools with powerful query capabilities:
Core Operations:
get_tools_by_domain(domain)- Filter by domain (weather, calendar, etc.)get_tools_by_tags(tags)- Filter by tags (forecast, event, etc.)get_tool(tool_id)- Get specific tool by IDlist_domains()- Get all available domainsget_summary()- Get registry statistics
Example:
from tools import ToolRegistry
registry = ToolRegistry()
# Get all weather tools
weather_tools = registry.get_tools_by_domain("weather")
# Returns: [current_weather, forecast]
# Get all tools tagged with "event"
event_tools = registry.get_tools_by_tags(["event"])
# Returns: [create_event, delete_event, list_events]
# Get summary
summary = registry.get_summary()
# {
# 'total_tools': 11,
# 'domains': ['weather', 'calendar', 'stock', 'email'],
# 'tools_by_domain': {...}
# }All agents now support automatic provider fallback - if one provider fails (e.g., Azure auth issues), the system automatically tries the next provider in the list.
How it works:
- Agent YAML specifies a list of providers to try
- System attempts each provider in order
- First successful provider is used
- If all fail, error is reported
Example configuration:
model:
providers:
- "openrouter" # Try first (easiest, no Azure auth needed)
- "azure" # Try second (if Azure CLI is authenticated)
- "openai" # Try third (if OpenAI API key is set)Benefits:
- ✅ No more agent failures due to Azure auth issues
- ✅ Seamless switching between providers
- ✅ Development-friendly (OpenRouter) with production Azure support
- ✅ Zero code changes needed
Supported Providers:
- OpenRouter: Access 100+ models via single API key
- Azure OpenAI: Enterprise-grade Azure integration
- OpenAI: Direct OpenAI API access
name: "Agent Name" # Required: Display name
description: "Agent description" # Required: Short description
tool_domains: # Optional: Domain filters
- domain1
- domain2
tool_tags: # Optional: Tag filters
- tag1
- tag2
exclude_tools: # Optional: Tools to exclude
- tool.name
instructions: | # Required: Agent prompt
Your instructions here...
# Model Configuration - Multi-Provider Support
model:
# Provider list (tries in order until one succeeds)
providers: # Required: List of providers to try
- "openrouter" # Recommended first choice
- "azure" # Fallback to Azure
- "openai" # Fallback to OpenAI
# Azure OpenAI configuration
endpoint: "https://..." # Azure OpenAI endpoint
deployment: "model-name" # Deployment name
credential_type: "azure_cli" # azure_cli or api_key
# OpenRouter/OpenAI config (from environment)
# OPENROUTER_API_KEY, OPENROUTER_MODEL
# OPENAI_API_KEY, OPENAI_MODELCreate a .env file for API keys:
# ============================================================================
# LLM Provider Configuration (choose one or all for automatic fallback)
# ============================================================================
# OpenRouter (Recommended for development - easiest setup)
OPENROUTER_API_KEY=sk-or-v1-your-key-here
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
OPENROUTER_MODEL=openai/gpt-4o-mini
OPENROUTER_APP_NAME=your-app-name
# Azure OpenAI (Enterprise production use)
AZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com/
AZURE_OPENAI_DEPLOYMENT=gpt-4o
AZURE_OPENAI_API_VERSION=2024-02-15-preview
# Note: Also requires `az login` for azure_cli authentication
# Direct OpenAI (Alternative to Azure)
OPENAI_API_KEY=sk-your-key-here
OPENAI_MODEL=gpt-4-turbo-preview
# ============================================================================
# Optional: Real API keys for tools
# ============================================================================
OPENWEATHER_API_KEY=your_key_here
ALPHA_VANTAGE_API_KEY=your_key_here
# ============================================================================
# Gmail Integration (Optional)
# ============================================================================
USE_REAL_EMAIL_API=true
GMAIL_CREDENTIALS_FILE=credentials.json
GMAIL_TOKEN_FILE=token.json
GMAIL_USER_EMAIL=your.email@gmail.com@tool(
domain="your_domain", # Required
name="tool_name", # Optional
description="What it does", # Optional
tags=["tag1", "tag2"], # Optional
mock=True, # Use mock data (True/False)
requires_api_key="API_KEY_ENV" # Environment variable name
)We welcome contributions! Here's how to get started:
- Fork the repository
- Clone your fork
- Create a virtual environment
- Install dependencies:
pip install -r requirements.txt - Create a branch:
git checkout -b feature/your-feature
- Create domain folder:
mkdir tools/your_domain - Add
__init__.py:touch tools/your_domain/__init__.py - Create tools: Add Python files with
@tooldecorators - Create agent YAML: Add
agents/your_domain_agent.yaml - Test: Run
python test_auto_discovery.py - Submit PR: Create a pull request with your changes
- Follow PEP 8 guidelines
- Use type hints for all functions
- Add docstrings to all public functions
- Use meaningful variable names
- Keep functions focused and small
Before submitting a PR:
# Test tool discovery
python -c "from tools import ToolRegistry; ToolRegistry().get_summary()"
# Test agent creation
python test_agent_factory.py
# Test your new domain
python test_auto_discovery.py- Update documentation for new features
- Add examples if adding new capabilities
- Ensure all tests pass
- Update README if needed
- Describe changes in PR description
Comprehensive documentation available in the docs/ folder:
- Dynamic Tool Architecture: Complete guide to the tool system
- Agent Workflow Architecture: Sequential and parallel workflows
- Parallel Execution Quickstart: Quick guide to parallel patterns
- Email Agent Demo: Step-by-step example of creating an agent
Problem: Tools not showing up in registry
Solution:
- Check file is in
tools/domain/directory - Ensure
@tooldecorator is present - Verify
__init__.pyexists in domain folder - Check logs for import errors
Problem: Agent YAML file not creating agent
Solution:
- Verify YAML syntax is correct
- Check domain names match tool domains
- Ensure Azure OpenAI credentials are configured
- Check logs for errors during discovery
Problem: Azure OpenAI connection fails
Solution:
- Verify endpoint URL is correct (must include
.azure.com) - Check Azure CLI is authenticated:
az account show - Verify deployment name matches your Azure setup
- Check network connectivity
The system includes 4 pre-built agents with 11 tools across 4 domains:
- Tools: 2 (current weather, forecast)
- Use Cases: Weather forecasts, current conditions
- Example: "What's the weather in Tokyo?"
- Tools: 3 (price, analysis, history)
- Use Cases: Stock prices, analyst ratings, historical data
- Example: "Analyze AAPL stock"
- Tools: 3 (send, read inbox, search)
- Use Cases: Email management, inbox checking
- Example: "Show me my unread emails"
- Tools: 3 (create event, list events, find free time)
- Use Cases: Schedule management, availability checking
- Example: "Find me a free slot tomorrow afternoon"
This project is licensed under the MIT License - see the LICENSE file for details.
- Microsoft Agent Framework: Core agent orchestration framework
- Azure OpenAI: LLM infrastructure
- Contributors: Thanks to all contributors who help improve this project
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- ✅ Dynamic tool discovery
- ✅ Automatic agent discovery
- ✅ YAML-based configuration
- ✅ Sequential workflows
- ✅ Parallel workflows
- ✅ DevUI integration
- 🔄 MCP Server implementation
- 🔄 Real API integrations (OpenWeatherMap, Alpha Vantage)
- 🔄 Tool versioning system
- 🔄 Agent performance monitoring
- 🔄 Hot-reload without restart
- 🔄 Plugin marketplace
- Multiple LLM provider support (OpenAI, Anthropic, etc.)
- Tool dependency management
- Conditional workflow routing
- Agent-to-agent communication
- Distributed agent execution
- Web-based agent configuration UI
Made with ❤️ using Microsoft Agent Framework
Star ⭐ this repo if you find it useful!