Genesis Nexus - Protocole A2A Détaillé
Spécification complète du protocole Agent-to-Agent (A2A).
📡 Vue d'ensemble du Protocole A2A
Le protocole A2A (Agent-to-Agent) est le langage de communication universel entre tous les agents de l'écosystème Genesis.
📨 Types de Messages
1. REQUEST
interface RequestMessage {
// En-tête
id: string // UUID unique
type: 'REQUEST'
version: '1.0'
// Routing
from: AgentId // Expéditeur
to: AgentId | 'broadcast' // Destinataire
correlationId?: string // Pour lier response
// Sémantique
intent: string // Intention (ex: "analyze_data")
confidence: number // 0-1, confiance dans l'intention
entities: Entity[] // Entités extraites
// Payload
payload: unknown // Données de la requête
context: ExecutionContext // Contexte d'exécution
// Qualité de service
priority: Priority // LOW, NORMAL, HIGH, CRITICAL
timeout?: number // ms
ttl?: number // Time to live (ms)
// Sécurité
timestamp: number // Unix timestamp (nanoseconds)
signature: string // Signature Ed25519
publicKey: string // Clé publique de l'expéditeur
// Options
options: {
requiresAck?: boolean // Accusé de réception requis
requiresResponse?: boolean // Réponse requise
allowPartialResponse?: boolean
maxResponseTime?: number
}
}
2. RESPONSE
interface ResponseMessage {
id: string
type: 'RESPONSE'
version: '1.0'
// Correlation
correlationId: string // ID de la requête originale
requestId: string // ID du message REQUEST
// Routing
from: AgentId
to: AgentId
// Résultat
status: 'SUCCESS' | 'FAILURE' | 'PARTIAL'
data?: unknown // Données de réponse
error?: ErrorDetails // Détails d'erreur
// Qualité
confidence?: number // Confiance dans la réponse
sources?: string[] // Sources des données
processingTime?: number // ms
// Sécurité
timestamp: number
signature: string
publicKey: string
}
interface ErrorDetails {
code: string // Code d'erreur
message: string // Message lisible
details?: Record<string, unknown>
stack?: string // Stack trace
retryable: boolean // Peut-on retry?
}
3. EVENT
interface EventMessage {
id: string
type: 'EVENT'
version: '1.0'
// Routing
from: AgentId
to?: AgentId | 'broadcast' // Souvent broadcast
// Événement
eventType: string // ex: "workflow.completed"
eventName: string // Nom lisible
// Données
payload: unknown
metadata: {
schemaVersion: string
contentType: string
}
// Delivery
deliveryGuarantee: 'at-most-once' | 'at-least-once' | 'exactly-once'
deduplicationId?: string // Pour exactly-once
// Sécurité
timestamp: number
signature: string
publicKey: string
}
4. ERROR
interface ErrorMessage {
id: string
type: 'ERROR'
version: '1.0'
// Correlation
correlationId?: string
originalMessageId?: string
// Routing
from: AgentId
to: AgentId
// Erreur
errorType: 'ROUTING_ERROR' | 'TIMEOUT' | 'VALIDATION_ERROR' | 'AGENT_ERROR'
errorCode: string
message: string
details?: Record<string, unknown>
// Recovery
retryAfter?: number // ms avant de retry
fallbackSuggestion?: AgentId // Agent alternatif
// Sécurité
timestamp: number
signature: string
publicKey: string
}
🎯 Intent Classification
Intentions Standard
type StandardIntent =
| 'query_data' // Interroger des données
| 'analyze_data' // Analyser des données
| 'transform_data' // Transformer des données
| 'store_data' // Stocker des données
| 'retrieve_data' // Récupérer des données
| 'execute_workflow' // Exécuter un workflow
| 'monitor_status' // Surveiller un status
| 'send_notification' // Envoyer une notification
| 'schedule_task' // Planifier une tâche
| 'cancel_task' // Annuler une tâche
| 'get_capability' // Obtenir les capacités
| 'register_agent' // Enregistrer un agent
| 'unregister_agent' // Désenregistrer un agent
| 'health_check' // Vérifier la santé
| 'authenticate' // Authentifier
| 'authorize' // Autoriser
Extraction d'Entités
interface Entity {
type: string // Type d'entité
value: string // Valeur extraite
confidence: number // 0-1
startOffset?: number // Position dans le texte
endOffset?: number
metadata?: Record<string, unknown>
}
// Exemples d'entités
const entities: Entity[] = [
{
type: 'workflow_id',
value: 'etl-pipeline-123',
confidence: 0.98
},
{
type: 'date_range',
value: '2024-01-01 to 2024-01-31',
confidence: 0.95,
metadata: {
startDate: '2024-01-01',
endDate: '2024-01-31'
}
},
{
type: 'agent_name',
value: 'data-analyst',
confidence: 0.99
}
]
🔄 Message Flow
Request-Response Pattern
Publish-Subscribe Pattern
Request-Stream Pattern
🔐 Sécurité des Messages
Signature
async function signMessage(
message: A2AMessage,
privateKey: Uint8Array
): Promise<string> {
// Payload à signer (exclut signature)
const payload = {
id: message.id,
type: message.type,
from: message.from,
to: message.to,
intent: message.intent,
payload: message.payload,
timestamp: message.timestamp
}
const encoder = new TextEncoder()
const data = encoder.encode(JSON.stringify(payload))
// Signer avec Ed25519
const signature = await crypto.subtle.sign(
'Ed25519',
privateKey,
data
)
return bytesToBase64(new Uint8Array(signature))
}
Vérification
async function verifyMessage(
message: A2AMessage,
publicKey: Uint8Array
): Promise<boolean> {
const payload = {
id: message.id,
type: message.type,
from: message.from,
to: message.to,
intent: message.intent,
payload: message.payload,
timestamp: message.timestamp
}
const encoder = new TextEncoder()
const data = encoder.encode(JSON.stringify(payload))
const signature = base64ToBytes(message.signature)
return await crypto.subtle.verify(
'Ed25519',
publicKey,
signature,
data
)
}
📊 Quality of Service
Priority Levels
enum Priority {
LOW = 0, // Traitement quand possible
NORMAL = 1, // Traitement standard
HIGH = 2, // Traitement prioritaire
CRITICAL = 3 // Traitement immédiat
}
interface QoSConfig {
priority: Priority
timeout?: number
ttl?: number
retry?: {
maxAttempts: number
initialInterval: number
backoffCoefficient: number
}
}
Delivery Guarantees
enum DeliveryGuarantee {
AT_MOST_ONCE = 'at-most-once', // Peut être perdu
AT_LEAST_ONCE = 'at-least-once', // Peut être dupliqué
EXACTLY_ONCE = 'exactly-once' // Exactement une fois
}
// Implémentation at-least-once
async function sendWithRetry(
message: A2AMessage,
config: RetryConfig
): Promise<void> {
let lastError: Error
for (let attempt = 1; attempt <= config.maxAttempts; attempt++) {
try {
await sendMessage(message)
return // Succès
} catch (error) {
lastError = error
const delay = config.initialInterval * Math.pow(
config.backoffCoefficient,
attempt - 1
)
await sleep(delay)
}
}
throw lastError
}
// Implémentation exactly-once
async function sendExactlyOnce(
message: A2AMessage,
deduplicationId: string
): Promise<void> {
// Vérifier si déjà envoyé
const exists = await dedupStore.exists(deduplicationId)
if (exists) {
return // Déjà envoyé
}
// Envoyer et marquer comme envoyé
await sendMessage(message)
await dedupStore.set(deduplicationId, message.id, { ttl: 3600 })
}