File size: 4,765 Bytes
0c591a7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# 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.