The A2A (Agent-to-Agent) Protocol enables Brightsy agents to communicate and collaborate with other agents, both within Brightsy and across external platforms. This creates a network of specialized agents that can work together to solve complex problems.
What is A2A?
A2A is an open standard protocol that allows AI agents to:
- Discover each other's capabilities
- Delegate tasks to specialized agents
- Maintain multi-turn conversations with context
- Stream real-time responses
- Work across different platforms and providers
Features & Capabilities
- Internal Agent Connections: Brightsy agents can call other Brightsy agents
- External Agent Connections: Connect to A2A-compliant agents on other platforms
- Multi-Turn Conversations: Maintain context across multiple interactions
- Real-Time Streaming: Get live updates via Server-Sent Events (SSE)
- Task Management: Track conversation history and status
- Flexible Communication: Choose between A2A protocol or direct calls
Connecting Agents
Internal Brightsy-to-Brightsy Connections
Connect agents within your Brightsy workspace:
- Navigate to Agents → Select your agent → Connected Agents
- Click Add Connected Agent and select another Brightsy agent
- Toggle Use A2A Protocol to enable A2A communication (optional)
- Save the connection
When to use A2A for internal connections:
- Need conversation history and audit trails
- Want real-time streaming updates
- Building complex multi-agent workflows
- Preparing to expose agents externally
When to use Direct mode:
- Maximum performance required
- Simple, high-frequency calls
- Don't need persistent task tracking
External Agent Connections
Connect to agents on other A2A-compliant platforms:
- Navigate to Agents → Select your agent → External A2A Agents
- Enter the external agent's A2A endpoint URL
- Click Discover & Connect
- The agent card will be fetched and registered
- Configure authentication if required
Once connected, your agent automatically gains access to the external agent through the call_external_a2a_agent tool.
AI Agent Tools
Internal Agent Communication
connectedAgentRequest - Call another Brightsy agent
connectedAgentRequest({
agent_id: "weather-agent-id",
content: "What's the weather in Sacramento?",
a2a_task_id?: "optional-task-id" // For continuing specific conversations
})
Response includes:
- The agent's answer
- Task ID for conversation continuity
- Full message trace
External Agent Communication
call_external_a2a_agent - Call an external A2A agent
call_external_a2a_agent({
external_agent_id: "registered-external-agent-id",
message: "Analyze this data...",
a2a_task_id?: "optional-task-id" // For continuing conversations
})
Multi-Turn Conversations
A2A automatically maintains conversation context across multiple calls:
First interaction:
User: Ask the weather agent about Sacramento
Agent A → Weather Agent: "What's the weather in Sacramento?"
Response: [A2A Task: abc-123 - New conversation started]
The weather is sunny, 75°F
Follow-up (automatic context):
User: Ask if it's good for hiking
Agent A → Weather Agent: "Is that good for hiking?"
(Automatically continues task abc-123)
Response: [A2A Task: abc-123 - Conversation continued]
Yes, 75°F and sunny is perfect for hiking!
The weather agent sees both messages and can reference the previous context naturally.
Example Use Cases
Multi-Agent Workflow
User: "Research and write a blog post about quantum computing" Writing Agent (orchestrator) ↓ calls Research Agent via A2A ↓ "Find latest quantum computing breakthroughs" ↓ Research Agent returns findings ↓ Writing Agent calls Image Agent via A2A ↓ "Generate a diagram of a quantum circuit" ↓ Image Agent returns image ↓ Writing Agent compiles blog post with research and images
External Agent Integration
Brightsy Agent → External Data Analyst (Python specialist) "Analyze this CSV file and find trends" External Agent processes data ← Returns statistical analysis Brightsy Agent → External Visualization Agent "Create charts from this analysis" External Agent generates visualizations ← Returns chart images Brightsy Agent combines results and presents to user
Agent Discovery & Agent Cards
Every A2A agent exposes an "agent card" that describes its capabilities:
{
"id": "weather-agent",
"name": "Weather Information Agent",
"description": "Provides current weather data and forecasts",
"skills": [
{
"name": "current_weather",
"description": "Get current weather for any location"
},
{
"name": "forecast",
"description": "Get weather forecast up to 7 days"
}
],
"capabilities": [
{ "type": "streaming", "supported": true },
{ "type": "multi-turn", "supported": true }
]
}
Accessing agent cards:
GET /api/v1beta/agent/{agentId}/a2a/card
API Endpoints
Agent Card Discovery
GET /api/v1beta/agent/{agentId}/a2a/card
Returns the agent's A2A card with capabilities and skills.
Task Management
# Create new task
POST /api/v1beta/agent/{agentId}/a2a/tasks
Body: { "message": { "role": "user", "content": [...] } }
# Get task status (polling)
GET /api/v1beta/agent/{agentId}/a2a/tasks/{taskId}
# Stream task updates (recommended)
GET /api/v1beta/agent/{agentId}/a2a/tasks/{taskId}/stream
# Continue conversation
POST /api/v1beta/agent/{agentId}/a2a/tasks/{taskId}
Body: { "message": { "role": "user", "content": [...] } }
# Cancel task
DELETE /api/v1beta/agent/{agentId}/a2a/tasks/{taskId}
Connection Management
# Connect to external agent
POST /api/v1beta/agent/{agentId}/external-a2a-connections
Body: { "endpoint": "https://external-agent.com/a2a" }
# List external connections
GET /api/v1beta/agent/{agentId}/external-a2a-connections
# Remove connection
DELETE /api/v1beta/agent/{agentId}/external-a2a-connections/{externalAgentId}
Authentication
For Brightsy Users (Calling External Agents)
When your Brightsy agents call external A2A agents:
- Configure authentication per connection in the External A2A Agents section
- Support for various auth methods (Bearer tokens, OAuth, etc.)
- Credentials stored securely per connection
- Authentication is automatic once configured
For External Agents (Calling Brightsy Agents)
External agents can connect to your Brightsy agents using two methods:
Method 1: OAuth 2.1 (Recommended)
For user-authorized access with full OAuth 2.1 support:
{
"auth": {
"type": "bearer",
"config": { "required": true }
},
"securitySchemes": {
"oauth2": {
"flows": {
"authorizationCode": {
"authorizationUrl": "https://brightsy.ai/oauth/authorize",
"tokenUrl": "https://brightsy.ai/oauth/token",
"scopes": { "brightsy:api": "Access Brightsy APIs" }
}
}
}
}
}
Steps:
- Register OAuth client:
POST /oauth/register - User authorizes access
- Exchange code for access token
- Use token to call A2A endpoints:
Authorization: Bearer {token}
Method 2: API Key (Simple)
For direct system-to-system access:
- Create an API key in your agent settings
- Provide the API key to the external agent
- External agent uses it as Bearer token:
Authorization: Bearer {api_key}
Agent Card Discovery (shows auth requirements):
GET /api/v1beta/agent/{agentId}/a2a/card
# Public endpoint - returns authentication requirements
For complete OAuth flow examples and security details, see our External Agent Authentication Guide.
Streaming vs Polling
A2A supports two methods for getting results:
Streaming (Recommended)
- Real-time updates via Server-Sent Events (SSE)
- Single persistent connection
- Instant notification when task completes
- Lower latency and server load
const stream = await fetch(
`/api/v1beta/agent/${agentId}/a2a/tasks/${taskId}/stream`,
{ headers: { 'Accept': 'text/event-stream' } }
);
// Parse SSE events
for await (const event of stream) {
if (event.data) {
const update = JSON.parse(event.data);
if (update.result.final) {
// Task completed
return update.result.task;
}
}
}
Polling (Fallback)
- HTTP GET requests repeated at intervals
- Simple client implementation
- Works with restrictive firewalls
let attempts = 0;
while (attempts < 60) {
const response = await fetch(
`/api/v1beta/agent/${agentId}/a2a/tasks/${taskId}`
);
const task = await response.json();
if (task.task_status === 'completed') {
return task;
}
await sleep(1000);
attempts++;
}
Programmatic Access
BrightsyClient SDK
The Brightsy client SDK provides a consistent, organized API for all A2A operations with full OAuth 2.1 support:
Authentication Methods
The SDK supports multiple authentication methods:
import { BrightsyClient } from '@brightsy/client';
// Method 1: API Key (simple)
const client = new BrightsyClient({
api_key: 'your-api-key',
endpoint: 'https://your-instance.brightsy.ai'
});
// Method 2: OAuth 2.1 (user-authorized, auto-refresh)
const client = new BrightsyClient({
authMode: 'oauth',
oauthAccessToken: tokens.access_token,
oauthRefreshToken: tokens.refresh_token,
oauthClientId: 'your-client-id',
oauthClientSecret: 'your-client-secret', // Optional
endpoint: 'https://your-instance.brightsy.ai',
// Get notified when tokens refresh automatically
onTokenRefresh: (accessToken, refreshToken) => {
// Save new tokens
saveTokens({ accessToken, refreshToken });
}
});
// Method 3: Cookie-based (browser sessions)
const client = new BrightsyClient({
authMode: 'cookie',
endpoint: 'https://your-instance.brightsy.ai'
});
OAuth 2.1 Flow
For external agents that need user-authorized access:
import { OAuthClient } from '@brightsy/client';
// 1. Register OAuth client
const oauthClient = new OAuthClient({
clientId: 'your-client-id', // From registration
clientSecret: 'your-client-secret',
redirectUri: 'http://localhost:3000/callback'
});
// Register your application (one-time)
const credentials = await oauthClient.register({
client_name: 'My External Agent',
redirect_uris: ['http://localhost:3000/callback'],
scopes: ['brightsy:api']
});
// 2. Build authorization URL
const { url, state, codeVerifier } = await oauthClient.buildAuthorizationUrl();
// Store state and codeVerifier, redirect user to url
// 3. Exchange authorization code for tokens (in callback)
const tokens = await oauthClient.exchangeCode(code, codeVerifier);
// 4. Use tokens with BrightsyClient (auto-refresh enabled)
const client = new BrightsyClient({
authMode: 'oauth',
oauthAccessToken: tokens.access_token,
oauthRefreshToken: tokens.refresh_token,
oauthClientId: credentials.client_id,
oauthClientSecret: credentials.client_secret,
onTokenRefresh: (accessToken, refreshToken) => {
// Tokens are refreshed automatically before expiry
console.log('Tokens refreshed!');
saveTokens({ accessToken, refreshToken });
}
});
OAuth Features:
- ✅ Authorization Code flow with PKCE (S256)
- ✅ Automatic token refresh before expiry
- ✅ Dynamic client registration
- ✅ Token revocation
- ✅ Server metadata discovery
- ✅ Works in browser and Node.js
For complete OAuth documentation, see the OAuth Authentication Guide.
A2A Operations
Get agent card - organized under a2a namespace:
const card = await client.agent(agentId).a2a.getCard();
// Task operations - organized under a2a.tasks namespace const task = await client.agent(agentId).a2a.tasks.create({ role: 'user', content: [{ type: 'text', text: 'Hello!' }] });
// Stream response - real-time updates via SSE await client.agent(agentId).a2a.tasks.stream(task.id, (update) => { console.log('Status:', update.task_status); console.log('Messages:', update.messages.length); });
// Append message for multi-turn conversation await client.agent(agentId).a2a.tasks.append(task.id, { role: 'user', content: [{ type: 'text', text: 'Follow-up question' }] });
// Cancel a task if needed await client.agent(agentId).a2a.tasks.cancel(task.id);
// Connection management - organized under a2a.connections namespace await client.agent(agentId).a2a.connections.create({ endpoint: 'https://external.com/a2a', auth_config: { type: 'bearer', token: 'xyz' } // Optional });
// List all external connections const connections = await client.agent(agentId).a2a.connections.list();
// Remove a connection await client.agent(agentId).a2a.connections.delete(externalAgentId);
**Consistent API Pattern:**
The A2A SDK follows the same pattern as CMS operations for consistency:
```typescript
// CMS operations
client.cma.from('posts').select('*')
client.cda.from('posts').where({ published: true })
// A2A operations - same pattern!
client.agent(id).a2a.tasks.create(...)
client.agent(id).a2a.connections.list()
Best Practices
Agent Design
- Single Responsibility: Each agent should have a clear, focused purpose
- Clear Skills: Define specific skills in the agent card
- Error Handling: Handle failures gracefully and provide helpful messages
- Rate Limiting: Implement rate limits for external calls
Multi-Agent Workflows
- Orchestration: Designate one agent as the orchestrator
- Task Delegation: Break complex tasks into smaller agent-specific subtasks
- Context Management: Keep conversation context relevant and concise
- Failure Recovery: Design workflows to handle agent failures
Performance
- Use Streaming: Prefer SSE streaming over polling for better performance
- Connection Reuse: Maintain persistent connections when possible
- Caching: Cache agent cards and capability information
- Async Processing: Use A2A's async nature for long-running tasks
Security
- API Key Rotation: Regularly rotate API keys for external connections
- Least Privilege: Grant agents only the permissions they need
- Audit Logging: Monitor agent-to-agent interactions
- Input Validation: Validate all messages and parameters
Conversation Management
- Context Limits: Be aware of conversation length and context window limits
- Reset When Needed: Start new conversations for unrelated topics
- Explicit Task IDs: Use explicit task IDs when managing multiple parallel conversations
- Cleanup: Periodically clean up completed tasks
Troubleshooting
Connection Issues
Problem: "External agent not found"
- Verify the agent endpoint URL is correct
- Check the external agent is accessible (try curl/Postman)
- Ensure the agent card endpoint returns valid JSON
Problem: "Authentication failed"
- Verify API key is correct and active
- Check the authorization header format
- Ensure the agent has permission to be called
Task Issues
Problem: Task stuck in "running" state
- Check the target agent's logs for errors
- Verify the agent is processing the request
- Consider timeout and retry logic
Problem: "Task not found"
- Task may have expired or been cleaned up
- Start a new conversation
- Check task ID is correct
Streaming Issues
Problem: Stream disconnects frequently
- Check network stability and firewall settings
- Verify SSE is not being buffered by proxies
- Implement reconnection logic with exponential backoff
Related Documentation
A2A Protocol Specification
Brightsy implements the official A2A protocol specification. For detailed protocol documentation, visit: