Some checks are pending
Documentation Lint & Validation / Markdown Linting (push) Waiting to run
Documentation Lint & Validation / Validate mdBook Configuration (push) Waiting to run
Documentation Lint & Validation / Content & Structure Validation (push) Waiting to run
Documentation Lint & Validation / Lint & Validation Summary (push) Blocked by required conditions
mdBook Build & Deploy / Build mdBook (push) Waiting to run
mdBook Build & Deploy / Documentation Quality Check (push) Blocked by required conditions
mdBook Build & Deploy / Deploy to GitHub Pages (push) Blocked by required conditions
mdBook Build & Deploy / Notification (push) Blocked by required conditions
Rust CI / Security Audit (push) Waiting to run
Rust CI / Check + Test + Lint (nightly) (push) Waiting to run
Rust CI / Check + Test + Lint (stable) (push) Waiting to run
260 lines
6.7 KiB
Markdown
260 lines
6.7 KiB
Markdown
# vapora-a2a
|
|
|
|
**Agent-to-Agent (A2A) Protocol Server** - Production-ready implementation of the A2A specification for VAPORA.
|
|
|
|
## Features
|
|
|
|
- ✅ **Full A2A Protocol Compliance** - JSON-RPC 2.0, Agent Card discovery
|
|
- ✅ **SurrealDB Persistence** - Tasks survive restarts, production-ready storage
|
|
- ✅ **NATS Async Coordination** - Real-time task completion via message queue
|
|
- ✅ **Prometheus Metrics** - Full observability with `/metrics` endpoint
|
|
- ✅ **Type-Safe** - Rust compile-time guarantees for protocol correctness
|
|
- ✅ **Integration Tests** - 5 comprehensive end-to-end tests
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ A2A HTTP Server (Axum) │
|
|
│ /.well-known/agent.json | /a2a | /metrics │
|
|
└────────────────┬────────────────────────────────┘
|
|
│
|
|
┌───────┴────────┐
|
|
│ │
|
|
┌────▼─────┐ ┌──────▼────────┐
|
|
│ Bridge │ │ TaskManager │
|
|
│ (NATS) │ │ (SurrealDB) │
|
|
└────┬─────┘ └──────┬────────┘
|
|
│ │
|
|
│ ┌──────▼────────┐
|
|
└────────►│ AgentCoord │
|
|
└───────────────┘
|
|
```
|
|
|
|
### Components
|
|
|
|
1. **CoordinatorBridge** - Maps A2A tasks to internal agent coordination
|
|
- NATS subscribers for TaskCompleted/TaskFailed events
|
|
- DashMap for async result delivery via oneshot channels
|
|
- Graceful degradation if NATS unavailable
|
|
|
|
2. **TaskManager** - Persistent task storage and lifecycle
|
|
- SurrealDB integration with Surreal<Client>
|
|
- Parameterized queries for security
|
|
- Tasks survive server restarts
|
|
|
|
3. **Server** - HTTP endpoints (Axum)
|
|
- `GET /.well-known/agent.json` - Agent discovery
|
|
- `POST /a2a` - Task dispatch
|
|
- `GET /a2a/tasks/{task_id}` - Status query
|
|
- `GET /health` - Health check
|
|
- `GET /metrics` - Prometheus metrics
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
```bash
|
|
# Start SurrealDB
|
|
docker run -d -p 8000:8000 \
|
|
surrealdb/surrealdb:latest \
|
|
start --bind 0.0.0.0:8000
|
|
|
|
# Start NATS (optional, graceful degradation)
|
|
docker run -d -p 4222:4222 nats:latest
|
|
|
|
# Run migration
|
|
surrealdb import --conn ws://localhost:8000 \
|
|
--user root --pass root \
|
|
migrations/007_a2a_tasks_schema.surql
|
|
```
|
|
|
|
### Run Server
|
|
|
|
```bash
|
|
cargo run --bin vapora-a2a -- \
|
|
--host 127.0.0.1 \
|
|
--port 8003 \
|
|
--version 1.0.0
|
|
```
|
|
|
|
Server will start on `http://127.0.0.1:8003`
|
|
|
|
### Using the Client
|
|
|
|
```rust
|
|
use vapora_a2a_client::{A2aClient, RetryPolicy};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let client = A2aClient::new("http://localhost:8003");
|
|
|
|
// Discover agent capabilities
|
|
let agent_card = client.discover_agent().await?;
|
|
println!("Agent: {} v{}", agent_card.name, agent_card.version);
|
|
|
|
// Dispatch task
|
|
let task_id = client.dispatch_task(
|
|
"task-123".to_string(),
|
|
"Write hello world function".to_string(),
|
|
Some("In Rust".to_string()),
|
|
Some("developer".to_string()),
|
|
).await?;
|
|
|
|
// Poll for completion
|
|
loop {
|
|
let status = client.get_task_status(&task_id).await?;
|
|
match status.state.as_str() {
|
|
"completed" => {
|
|
println!("Result: {:?}", status.result);
|
|
break;
|
|
}
|
|
"failed" => {
|
|
eprintln!("Error: {:?}", status.error);
|
|
break;
|
|
}
|
|
_ => tokio::time::sleep(Duration::from_millis(500)).await,
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
```bash
|
|
# SurrealDB
|
|
SURREAL_URL=ws://localhost:8000
|
|
SURREAL_USER=root
|
|
SURREAL_PASS=root
|
|
|
|
# NATS (optional)
|
|
NATS_URL=nats://localhost:4222
|
|
|
|
# Server
|
|
A2A_HOST=0.0.0.0
|
|
A2A_PORT=8003
|
|
A2A_VERSION=1.0.0
|
|
```
|
|
|
|
### CLI Arguments
|
|
|
|
```bash
|
|
vapora-a2a \
|
|
--host 0.0.0.0 \
|
|
--port 8003 \
|
|
--version 1.0.0
|
|
```
|
|
|
|
## Metrics
|
|
|
|
Exposed at `http://localhost:8003/metrics` in Prometheus text format:
|
|
|
|
- `vapora_a2a_tasks_total{status="waiting|working|completed|failed"}` - Task counts
|
|
- `vapora_a2a_task_duration_seconds{status="completed|failed"}` - Task execution time
|
|
- `vapora_a2a_nats_messages_total{subject,result}` - NATS message handling
|
|
- `vapora_a2a_db_operations_total{operation,result}` - Database operations
|
|
- `vapora_a2a_coordinator_assignments_total{skill,result}` - Coordinator assignments
|
|
|
|
## Testing
|
|
|
|
### Unit Tests
|
|
|
|
```bash
|
|
cargo test -p vapora-a2a --lib
|
|
```
|
|
|
|
### Integration Tests
|
|
|
|
Require SurrealDB + NATS running:
|
|
|
|
```bash
|
|
# Start dependencies
|
|
docker compose up -d surrealdb nats
|
|
|
|
# Run tests
|
|
cargo test -p vapora-a2a --test integration_test -- --ignored
|
|
|
|
# Tests:
|
|
# 1. Task persistence after restart
|
|
# 2. NATS completion updates DB
|
|
# 3. Task state transitions
|
|
# 4. Task failure handling
|
|
# 5. End-to-end dispatch with timeout
|
|
```
|
|
|
|
## Protocol Compliance
|
|
|
|
Implements [A2A Protocol Specification](https://a2a-spec.dev):
|
|
|
|
- ✅ Agent Card (`/.well-known/agent.json`)
|
|
- ✅ Task dispatch (`POST /a2a`)
|
|
- ✅ Status query (`GET /a2a/tasks/{id}`)
|
|
- ✅ JSON-RPC 2.0 envelope
|
|
- ✅ Task lifecycle (waiting → working → completed|failed)
|
|
- ✅ Artifact support
|
|
- ✅ Error handling
|
|
|
|
## Production Deployment
|
|
|
|
See [ADR-0001](../../docs/architecture/adr/0001-a2a-protocol-implementation.md) and [ADR-0002](../../docs/architecture/adr/0002-kubernetes-deployment-strategy.md).
|
|
|
|
### Kubernetes
|
|
|
|
```bash
|
|
kubectl apply -k kubernetes/overlays/prod/
|
|
```
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
docker build -t vapora-a2a:latest -f Dockerfile .
|
|
docker run -p 8003:8003 \
|
|
-e SURREAL_URL=ws://surrealdb:8000 \
|
|
-e NATS_URL=nats://nats:4222 \
|
|
vapora-a2a:latest
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Tasks not persisting
|
|
|
|
Check SurrealDB connection:
|
|
```bash
|
|
# Verify connection
|
|
curl http://localhost:8000/health
|
|
|
|
# Check migration applied
|
|
surrealdb sql --conn ws://localhost:8000 \
|
|
--user root --pass root --ns test --db main \
|
|
"SELECT * FROM a2a_tasks LIMIT 1;"
|
|
```
|
|
|
|
### Tasks not completing
|
|
|
|
Check NATS connection:
|
|
```bash
|
|
# Subscribe to completion events
|
|
nats sub "vapora.tasks.completed"
|
|
|
|
# Server will log warnings if NATS unavailable
|
|
```
|
|
|
|
### Metrics not showing
|
|
|
|
```bash
|
|
# Check metrics endpoint
|
|
curl http://localhost:8003/metrics | grep vapora_a2a
|
|
```
|
|
|
|
## Related Crates
|
|
|
|
- **vapora-a2a-client** - Client library for calling A2A servers
|
|
- **vapora-agents** - Agent coordinator and registry
|
|
- **vapora-backend** - Main VAPORA REST API
|
|
|
|
## License
|
|
|
|
MIT OR Apache-2.0
|