Volver

Contrato A2A por WebSocket

Esta pagina documenta que espera la comunicacion A2A, como el servidor gestiona muchos agentes y que comandos permiten descubrir agentes, escribir por direccion y pedir consejo al Decision Agent.

Transporte

Endpoint A2A

ws://localhost:3000/ws/a2a

Se abre desde JavaScript o desde un proceso agente. No es una pagina navegable.

Formato

Mensajes JSON

Todo comando viaja como JSON con un campo obligatorio type. El servidor valida el payload antes de ejecutar.

Respuesta

Estado en vivo

Despues de cada comando, el servidor publica { "type": "state" } a todas las pantallas conectadas.

Seguridad

Autenticacion por token en MongoDB

La autenticacion aplica cuando un proceso externo quiere conectarse o registrarse como agente. Las pantallas de visualizacion no piden token: solo observan estado, directorio y logs. El servidor lee el token desde headers, busca ese valor en la coleccion usuarios de MongoDB y usa el identificador encontrado como usuario principal del agente.

Entrada Valor esperado Uso
x-a2a-token Token del usuario Header recomendado para Postman y agentes externos.
Authorization Bearer TOKEN Alternativa compatible con clientes HTTP comunes.
x-api-key Token del usuario Alias soportado para integraciones existentes.

El servidor busca el token en usuarios.token, usuarios.apiKey, usuarios.a2aToken, usuarios.accessToken, usuarios.tokens o usuarios.tokens.value.

MongoDB

Ejemplo de usuario con token

{
  "_id": "ObjectId(...)",
  "userId": "user-001",
  "email": "demo@local",
  "name": "Usuario demo",
  "token": "tok_demo_123",
  "active": true
}
Variables

Configuracion del servidor

MONGODB_URI=mongodb://localhost:27017
MONGODB_DB=a2a
MONGODB_USERS_COLLECTION=usuarios
MONGODB_AGENTS_COLLECTION=agentes
AUTH_TOKEN_HEADER=x-a2a-token
Arquitectura del servidor

Servidor dividido en 3 responsabilidades

Parte Responsabilidad Direccion / salida
Directory Mantiene la lista de agentes disponibles y conectados. Cada conexion online recibe una direccion unica nueva. directory.available, directory.connected, connectionId
Message Bridge Entrega mensajes directos entre un agente origen y otro agente destino usando la direccion temporal del destino. a2a.message.direct
Decision Agent Agente interno del servidor. Recibe consultas de proyecto y recomienda que agentes del directorio conviene usar. server://decision-agent

El servidor ya no esta pensado solo como puente A-B. Es un router A2A: muchos agentes pueden registrarse, pedir directorio, resolver direcciones y escribir a otros agentes.

Uso practico

Como probarlo desde Postman

  1. Abre Postman y crea una nueva request de tipo WebSocket.
  2. Usa esta URL: ws://localhost:3000/ws/a2a.
  3. En Headers agrega x-a2a-token: tok_demo_123.
  4. Presiona Connect. Si el token existe en MongoDB, Postman quedara escuchando mensajes.
  5. En el panel de mensajes, envia JSON crudo. Cada mensaje debe tener un type.
  6. El servidor respondera emitiendo mensajes state. Ahi veras el directorio, logs, actividades y direcciones.

Postman no debe abrir http://localhost:3000/ws/a2a. Debe ser una request WebSocket con ws://.

Postman paso 1

Registrar agente backend

{
  "type": "agent.start",
  "agent": {
    "id": "agent-backend",
    "name": "Agente Backend",
    "description": "Especialista en APIs, base de datos y seguridad.",
    "instruction": "Resuelve solo temas backend y pide apoyo si sale de tu area.",
    "delayMs": 1500
  }
}
Postman paso 2

Registrar agente frontend

{
  "type": "agent.start",
  "agent": {
    "id": "agent-frontend",
    "name": "Agente Frontend",
    "description": "Especialista en Angular, UI y experiencia de usuario.",
    "instruction": "Resuelve solo temas frontend y visuales.",
    "delayMs": 1200
  }
}
Postman paso 3

Pedir directorio conectado

{
  "type": "a2a.directory.request",
  "requester": "agent-backend",
  "mode": "connected"
}
Postman paso 4

Copiar direccion destino

En el mensaje state, busca:

{
  "directory": {
    "connected": [
      {
        "agentId": "agent-frontend",
        "connectionId": "addr_..."
      }
    ]
  }
}

Ese connectionId es la direccion temporal para escribirle a ese agente.

Postman paso 5

Enviar mensaje directo

{
  "type": "a2a.message.direct",
  "from": "agent-backend",
  "toAddress": "addr_pega_aqui_la_direccion",
  "text": "Necesito que revises la estructura visual de una plataforma academica."
}
Postman paso 6

Consultar Decision Agent

{
  "type": "a2a.decision.advise",
  "requester": "agent-backend",
  "project": "Crear una plataforma academica con API, dashboard, cursos, usuarios y reportes."
}
Tambien desde HTTP

Consultas simples con Postman normal

Si solo quieres leer informacion sin abrir WebSocket, usa requests HTTP GET:

Accion Metodo URL
Ver estado completo GET http://localhost:3000/api/agent/conversation
Ver directorio disponible GET http://localhost:3000/api/agent/directory?mode=available
Ver conectados GET http://localhost:3000/api/agent/directory?mode=connected
Ver manifiesto GET http://localhost:3000/api/agent/manifest

HTTP sirve para consultar. WebSocket sirve para operar el A2A en vivo y recibir eventos en tiempo real.

Cliente minimo

Probar desde Node.js

Tambien puedes probarlo con un script externo usando el paquete ws:

import WebSocket from 'ws';

const ws = new WebSocket('ws://localhost:3000/ws/a2a', {
  headers: {
    'x-a2a-token': 'tok_demo_123'
  }
});

ws.on('open', () => {
  ws.send(JSON.stringify({
    type: 'agent.start',
    agent: {
      id: 'agent-backend',
      name: 'Agente Backend',
      description: 'Especialista en APIs y base de datos.',
      instruction: 'Resuelve backend y consulta el directorio si necesita apoyo.',
      delayMs: 1000
    }
  }));
});

ws.on('message', (raw) => {
  console.log(JSON.parse(raw.toString()));
});
Que puedo hacer con A2A

Capacidades del canal

Capacidad Comando Para que sirve
Registrar agente agent.start El agente envia nombre, descripcion, instruccion y delay. El servidor lo pone online y le asigna una direccion unica nueva connectionId.
Detener agente agent.stop Marca al agente como down, borra su conexion temporal y lo deja fuera de conectados.
Pedir directorio a2a.directory.request Cualquier agente solicita al servidor la lista de agentes disponibles o conectados.
Escribir por direccion a2a.message.direct Un agente envia mensaje directo a otro usando su connectionId temporal.
Pedir decision a2a.decision.advise Un agente consulta al Decision Agent que agentes conviene usar para cumplir un proyecto.
Entregar recurso a2a.resource.deliver El servidor envia al agente texto, JSON, archivo, URL, elemento o recurso para que lo use como entrada.
Iniciar trabajo a2a.processing.start Ordena al agente empezar a procesar una tarea y cambia su actividad a procesando.
Terminar trabajo a2a.processing.finish El agente reporta resultado, el sistema lo muestra en chat y despues vuelve a idle.
Reportar agente libre a2a.agent.free El agente informa al servidor que ya termino o no tiene carga activa. El servidor actualiza su actividad a idle.
Enviar chat chat.send Permite mandar una tarea a un agente; este consulta el directorio y puede pedir apoyo a otro agente.
Conectar canal channel.connect Habilita el bus A2A. Para probar intercambio directo se recomiendan al menos dos agentes externos online, pero el servidor gestiona muchos agentes.
Registro

Levantar un agente

{
  "type": "agent.start",
  "agent": {
    "id": "agent-a",
    "name": "Agente backend",
    "description": "Especialista en APIs y base de datos.",
    "instruction": "Responde solo desde backend.",
    "delayMs": 5000
  }
}
Recurso

Entregar elemento o recurso

{
  "type": "a2a.resource.deliver",
  "target": "agent-a",
  "resource": {
    "kind": "json",
    "name": "brief-academico",
    "content": "{ \"pantallas\": [\"login\", \"cursos\"] }",
    "metadata": {
      "source": "usuario"
    }
  }
}
Directorio

Pedir agentes conectados

{
  "type": "a2a.directory.request",
  "requester": "agent-backend",
  "mode": "connected"
}
Puente

Escribir por direccion

{
  "type": "a2a.message.direct",
  "from": "agent-backend",
  "toAddress": "addr_7f4f...",
  "text": "Necesito que revises la propuesta frontend."
}
Decision Agent

Pedir consejo de agentes

{
  "type": "a2a.decision.advise",
  "requester": "agent-backend",
  "project": "Construir una plataforma academica con backend, frontend y reportes."
}
Control

Start processing

{
  "type": "a2a.processing.start",
  "target": "agent-a",
  "task": "Analiza el recurso recibido y propone estructura backend."
}
Control

El agente dice que esta libre

{
  "type": "a2a.agent.free",
  "target": "agent-a",
  "note": "Termine mi tarea actual y puedo recibir otra asignacion."
}
Contrato esperado

Que espera la comunicacion A2A

Campo Obligatorio Descripcion
type Si Nombre exacto del comando. El servidor lo usa para validar y enrutar.
target En comandos a agente ID del agente destino. Puede ser cualquier identificador registrado, por ejemplo agent-backend.
toAddress En a2a.message.direct Direccion temporal unica de conexion del agente destino. Cambia cada vez que ese agente se registra de nuevo.
requester En directorio y decision Agente que inicia la solicitud al servidor.
agent En agent.start Perfil completo del agente: nombre, especialidad, instruccion y delay.
resource En a2a.resource.deliver Entrada que el agente debe recibir: texto, JSON, URL, archivo, elemento o recurso generico.
task En a2a.processing.start Instruccion concreta para iniciar procesamiento.
result No Resultado que reporta el agente al terminar.
Servidor

Como gestiona el sistema

  1. Recibe un comando JSON por WebSocket.
  2. Valida el formato y el agente destino.
  3. Cambia estado: online, down, procesando, recibiendo, enviando o idle.
  4. Agrega mensajes visibles en el chat si el comando llega al agente.
  5. Agrega logs tecnicos.
  6. Emite el nuevo state a todos los HTML abiertos.
Estados

Control operacional

  • online: agente registrado con direccion temporal activa.
  • down: agente detenido.
  • recibiendo: recibio recurso o mensaje.
  • procesando: tiene una tarea activa.
  • enviando: esta reportando resultado.
  • idle: libre para recibir otra tarea.
Flujo recomendado

Secuencia para una tarea con recursos

  1. agent.start: cada agente se registra y recibe una direccion unica connectionId.
  2. a2a.directory.request: cualquier agente pide conectados o disponibles.
  3. a2a.decision.advise: un agente consulta que otros agentes conviene usar para el proyecto.
  4. a2a.message.direct: el agente escribe a otro usando su direccion temporal.
  5. a2a.resource.deliver: el servidor entrega elementos o recursos al agente destino.
  6. a2a.processing.start: el agente empieza a procesar.
  7. a2a.processing.finish: el agente registra resultado del procesamiento.
  8. a2a.agent.free: el agente reporta que ya esta disponible para otra tarea.

Con esto A2A no es solo chat. Es un canal de control para gestionar agentes, entradas, recursos, procesamiento, disponibilidad y observabilidad en tiempo real.