A comprehensive A2A (Agent-to-Agent) server implementation that provides seamless integration with the Minions protocol, enabling both focused single-document analysis and parallel processing capabilities for complex multi-document tasks.
- Overview
- Installation
- Quick Start
- Configuration
- Skills and Protocol Selection
- API Reference
- Authentication
- Testing
- Examples
- Troubleshooting
- Operations
- Contributing
A2A-Minions bridges the gap between A2A protocol agents and the Minions framework, providing:
- Dual Protocol Support: Skills for both Minion and Minions protocols
- Document Processing: Full support for text, files (including PDFs), and structured data
- Streaming Responses: Real-time task execution updates
- Cost-Efficient Architecture: Leverages both local and cloud models strategically
- A2A Protocol Compliance: Full implementation of the Agent-to-Agent protocol specification
- Multi-modal Input: Handles text, files (PDF), data (JSON), and images
- Authentication: API Keys, JWT tokens, and OAuth2 client credentials
- Task Management: Async task execution with status tracking
- Monitoring: Prometheus metrics for production observability
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ A2A Client │────│ A2A-Minions │────│ Minions Protocol│
│ │ │ Server │ │ │
│ • Skill Request │ │ • Skill Router │ │ • Local Model │
│ • Document Send │ │ • Message Conv. │ │ • Remote Model │
│ • Stream Listen │ │ • Task Manager │ │ • Parallel Proc.│
└─────────────────┘ └─────────────────┘ └─────────────────┘
Component Breakdown:
- A2A Server: Handles A2A protocol compliance and request routing
- Skill Router: Automatically selects appropriate Minions protocol based on skill ID
- Message Converter: Translates between A2A and Minions message formats
- Task Manager: Manages long-running tasks with streaming capabilities
- Client Factory: Creates and configures Minions protocol instances
- Python 3.10+
- Access to at least one supported model provider (Ollama, OpenAI, etc.)
- The main Minions repository
-
Clone and install Minions:
git clone <repository-url> cd minions pip install -e .
-
Install A2A-specific dependencies:
cd apps/minions-a2a pip install -r requirements.txt -
Set up environment variables (for model providers):
export OPENAI_API_KEY="your-openai-key" export ANTHROPIC_API_KEY="your-anthropic-key" # Optional export OLLAMA_HOST="http://localhost:11434" # Optional
# Check dependencies
python run_server.py --skip-checks
# Run with environment checks
python run_server.py💡 Want a simple frontend UI? For easier setup and testing, check out the web interface at
examples/webapp- it provides a user-friendly way to interact with the A2A-Minions server without needing to work with JSON-RPC directly!
# From the apps/minions-a2a directory
python run_server.py --port 8001The server will be available at http://localhost:8001.
# Test focused analysis (minion_query skill)
python tests/test_client_minion.py
# Test parallel processing (minions_query skill)
python tests/test_client_minions.py- Health check:
http://localhost:8001/health - Agent card:
http://localhost:8001/.well-known/agent.json
# Default configuration in config.py
class MinionsConfig:
# Model settings
local_provider: str = "ollama"
local_model: str = "llama3.2"
remote_provider: str = "openai"
remote_model: str = "gpt-4o-mini"
# Processing settings
max_rounds: int = 3
max_jobs_per_round: int = 5
num_tasks_per_round: int = 2
num_samples_per_task: int = 1
# Context settings
num_ctx: int = 128000
chunking_strategy: str = "chunk_by_section"The system automatically routes requests to the appropriate protocol based on the skill ID:
- Purpose: Focused analysis and single-document Q&A
- Protocol: Uses Minion (singular) for cost-efficient processing
- Best For: Specific questions, quick fact extraction, simple analysis
- Purpose: Complex parallel processing and multi-document analysis
- Protocol: Uses Minions (parallel) for distributed processing
- Best For: Large document analysis, multi-document processing, complex research
// Focused analysis
{
"metadata": {
"skill_id": "minion_query",
"max_rounds": 2
}
}
// Parallel processing
{
"metadata": {
"skill_id": "minions_query",
"max_rounds": 3,
"max_jobs_per_round": 5,
"num_tasks_per_round": 3
}
}GET /health # Health check
GET /.well-known/agent.json # Public agent card
GET /agent/authenticatedExtendedCard # Extended capabilities (auth required)
POST /oauth/token # OAuth2 token endpoint
GET /metrics # Prometheus metricsAll task operations use JSON-RPC 2.0 over HTTP POST to /:
{
"jsonrpc": "2.0",
"method": "tasks/send",
"params": {
"id": "task-uuid",
"message": {
"role": "user",
"parts": [
{"kind": "text", "text": "Your question here"},
{"kind": "text", "text": "Document content here"}
]
},
"metadata": {
"skill_id": "minion_query",
"max_rounds": 2
}
},
"id": "request-uuid"
}Use tasks/sendSubscribe method with Accept: text/event-stream header for real-time updates.
{
"jsonrpc": "2.0",
"method": "tasks/get",
"params": {"id": "task-uuid"},
"id": "request-uuid"
}{
"jsonrpc": "2.0",
"method": "tasks/cancel",
"params": {"id": "task-uuid"},
"id": "request-uuid"
}// Text input
{"kind": "text", "text": "Your content"}
// File input
{
"kind": "file",
"file": {
"name": "document.pdf",
"mimeType": "application/pdf",
"bytes": "base64-encoded-content"
}
}
// Data input
{
"kind": "data",
"data": {"key": "value", "nested": {"data": "structure"}}
}A2A-Minions supports multiple authentication methods following the A2A protocol specification:
-
API Key Authentication (Default)
- Header:
X-API-Key: <your-api-key> - Best for: Local testing, simple deployments
- Header:
-
Bearer Token Authentication (JWT)
- Header:
Authorization: Bearer <token> - Best for: Production deployments, time-limited access
- Header:
-
OAuth2 Client Credentials Flow
- Endpoint:
POST /oauth/token - Best for: Machine-to-machine authentication
- Endpoint:
# No authentication (testing only)
python run_server.py --no-auth
# Default authentication (generates API key)
python run_server.py
# Custom API key
python run_server.py --api-key "your-custom-api-key"Use the included CLI tools:
# API Keys
python manage_api_keys.py list
python manage_api_keys.py generate "my-client" --scopes minion:query tasks:read
python manage_api_keys.py revoke "abc12345"
# OAuth2 Clients
python manage_oauth2_clients.py list
python manage_oauth2_clients.py register "my-app" --scopes minion:query tasks:read
python manage_oauth2_clients.py revoke oauth2_xxxxxminion:query- Execute focused minion queriesminions:query- Execute parallel minions queriestasks:read- Read task status and resultstasks:write- Create and cancel tasks
# Get access token
curl -X POST http://localhost:8001/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=your-client-id" \
-d "client_secret=your-client-secret" \
-d "scope=minion:query tasks:read"
# Use token in requests
curl -H "Authorization: Bearer <token>" http://localhost:8001/agent/authenticatedExtendedCard-
Start server with test authentication:
python run_server.py --api-key "abcd" -
Run test suites:
# Test focused analysis python tests/test_client_minion.py # Test parallel processing python tests/test_client_minions.py # Custom server URL python tests/test_client_minion.py --base-url http://localhost:8001
- Health and discovery endpoints
- Basic functionality and context processing
- Document processing (PDF, JSON, multi-modal)
- Streaming responses
- Error handling and edge cases
- Task management (status, cancellation)
- Long context processing
import asyncio
from test_client import A2AMinionsTestClient
async def custom_test():
client = A2AMinionsTestClient("http://localhost:8000")
message = {
"role": "user",
"parts": [
{"kind": "text", "text": "Your question"},
{"kind": "text", "text": "Your document"}
]
}
metadata = {"skill_id": "minion_query", "max_rounds": 2}
response = await client.send_task(message, metadata)
task_id = response["result"]["id"]
result = await client.wait_for_completion(task_id)
print(f"Result: {result}")
await client.close()
asyncio.run(custom_test())message = {
"role": "user",
"parts": [
{
"kind": "text",
"text": "What are the key findings in this research paper?"
},
{
"kind": "text",
"text": "Research paper content here..."
}
]
}
metadata = {
"skill_id": "minion_query",
"local_provider": "ollama",
"local_model": "llama3.2",
"remote_provider": "openai",
"remote_model": "gpt-4o-mini",
"max_rounds": 2
}message = {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Analyze this document and extract performance metrics, categorize findings, and identify trends."
},
{
"kind": "file",
"file": {
"name": "large_report.pdf",
"mimeType": "application/pdf",
"bytes": "base64-encoded-pdf-content"
}
}
]
}
metadata = {
"skill_id": "minions_query",
"max_rounds": 3,
"max_jobs_per_round": 5,
"num_tasks_per_round": 3
}complex_data = {
"quarterly_reports": {
"Q1_2024": {"revenue": 2500000, "expenses": 1800000},
"Q2_2024": {"revenue": 2800000, "expenses": 2000000}
},
"performance_metrics": {
"customer_satisfaction": 4.7,
"employee_retention": 0.92
}
}
message = {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Calculate revenue growth and identify trends in this business data."
},
{
"kind": "data",
"data": complex_data
}
]
}
metadata = {
"skill_id": "minions_query",
"max_rounds": 2,
"max_jobs_per_round": 4
}async def stream_example():
client = A2AMinionsTestClient()
# Send streaming request
task_id = await client.send_task_streaming(message, metadata)
# Real-time updates are automatically handled
final_task = await client.wait_for_completion(task_id)
print(f"Final result: {final_task}")Symptoms: Wrong protocol being used, unexpected errors
Solution: Ensure skill_id is properly specified in metadata:
{"metadata": {"skill_id": "minion_query"}} // or "minions_query"Symptoms: Model responds "I don't have access to documents"
Solution:
- Verify file uploads are base64 encoded correctly
- Check logs for context validation messages
- Ensure document content is non-empty
Symptoms: "Unexpected keyword argument" errors
Solution: Verify skill and parameter compatibility:
minion_query: Uses basic parameters (max_rounds, images)minions_query: Uses parallel parameters (max_jobs_per_round, num_tasks_per_round)
Symptoms: Connection errors, authentication failures
Solution:
- Check environment variables are set correctly
- Verify model provider endpoints are accessible
- Ensure API keys have sufficient permissions
// For large documents
{
"skill_id": "minions_query",
"max_rounds": 2,
"max_jobs_per_round": 8,
"num_tasks_per_round": 4,
"chunking_strategy": "chunk_by_section"
}
// For quick responses
{
"skill_id": "minion_query",
"max_rounds": 1,
"local_model": "llama3.2:1b",
"remote_model": "gpt-4o-mini"
}import logging
logging.basicConfig(level=logging.DEBUG)The server exposes Prometheus metrics at /metrics:
# View metrics
curl http://localhost:8000/metricsKey metrics:
a2a_minions_requests_total: Request count by method and statusa2a_minions_request_duration_seconds: Request latencya2a_minions_tasks_total: Task count by skill and statusa2a_minions_task_duration_seconds: Task execution timea2a_minions_active_tasks: Currently running tasksa2a_minions_auth_attempts_total: Auth attempts by method
Prometheus configuration:
scrape_configs:
- job_name: 'a2a-minions'
static_configs:
- targets: ['localhost:8000']
metrics_path: '/metrics'
scrape_interval: 30sBefore deploying to production, review the comprehensive checklist:
Key areas covered:
- Environment configuration
- Security hardening
- Infrastructure requirements
- Monitoring setup
- Performance optimization
- Operational procedures
git clone <repository-url>
cd minions/apps/minions-a2a
python -m venv dev-env
source dev-env/bin/activate # On Windows: dev-env\Scripts\activate
pip install -r requirements.txt- Fork the repository
- Create a feature branch
- Implement changes with tests
- Update documentation
- Submit pull request
This project is licensed under the MIT License. See LICENSE file for details.
- Issues: Open a GitHub issue
- Discussions: Use GitHub Discussions
- Documentation: Check this README and inline code documentation
A2A-Minions - Bridging Agent-to-Agent communication with the power of the Minions protocol for efficient, scalable document processing and analysis.