Instant-SWOT-Agent / docs /a2a_architecture.md
vn6295337's picture
Initial commit: Instant SWOT Agent
0c591a7
# A2A Researcher Agent Architecture
## Overview
The Researcher agent supports two modes:
- **Direct Mode** (default): Calls MCP servers directly from the main process
- **A2A Mode**: Delegates to a standalone A2A server for parallel data fetching
Enable A2A mode by setting `USE_A2A_RESEARCHER=true` in your environment.
## Architecture
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Main Orchestrator (LangGraph) β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Researcher Node β”‚ β”‚
β”‚ β”‚ (src/nodes/researcher.py) β”‚ β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ if USE_A2A_RESEARCHER: β”‚ β”‚
β”‚ β”‚ β†’ A2A Client (researcher_a2a_client.py) β”‚ β”‚
β”‚ β”‚ else: β”‚ β”‚
β”‚ β”‚ β†’ Direct MCP calls β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚
β”‚ β”‚ JSON-RPC 2.0 over HTTP (A2A mode only) β”‚
β”‚ ↓ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Researcher A2A Server (optional, external) β”‚
β”‚ (a2a/researcher_server.py) β”‚
β”‚ β”‚
β”‚ Endpoints: β”‚
β”‚ - GET /.well-known/agent.json (Agent Card) β”‚
β”‚ - POST / (JSON-RPC: message/send, tasks/get) β”‚
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Financials β”‚ β”‚ Sentiment β”‚ β”‚ News β”‚ ... β”‚
β”‚ β”‚ MCP Server β”‚ β”‚ MCP Server β”‚ β”‚ MCP Server β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
## A2A Protocol
A2A (Agent-to-Agent) is Google's open protocol for agent interoperability.
Reference: https://github.com/google-a2a/A2A
### Agent Card
Served at `/.well-known/agent.json`:
```json
{
"name": "swot-researcher",
"version": "1.0.0",
"description": "Financial research agent for SWOT analysis",
"capabilities": {
"streaming": false,
"pushNotifications": false
},
"skills": [{
"id": "research-company",
"name": "Company Research",
"inputModes": ["text"],
"outputModes": ["text", "data"]
}]
}
```
### JSON-RPC Methods
| Method | Description |
|--------|-------------|
| `message/send` | Submit research task |
| `tasks/get` | Get task status/results |
| `tasks/cancel` | Cancel running task |
### Task Lifecycle
```
SUBMITTED β†’ WORKING β†’ COMPLETED
β†˜ FAILED
```
## File Structure
```
a2a/
β”œβ”€β”€ researcher_server.py # A2A server implementation
β”œβ”€β”€ agent_card.json # Agent capabilities metadata
└── mcp_aggregator.py # Calls MCP servers in parallel
src/nodes/
β”œβ”€β”€ researcher.py # Mode switch (A2A vs Direct)
└── researcher_a2a_client.py # A2A client wrapper
```
## Benefits of A2A Mode
| Aspect | Direct Mode | A2A Mode |
|--------|-------------|----------|
| Latency | Sequential MCP calls | Parallel MCP calls |
| Scaling | Coupled with orchestrator | Independent scaling |
| Fault Isolation | Shared process | Separate process |
| Reusability | Single workflow | Any A2A client |
## Fallback Behavior
If the A2A server is unavailable, the system falls back to direct mode automatically.