Endpoint A2A
ws://localhost:3000/ws/a2a
Se abre desde JavaScript o desde un proceso agente. No es una pagina navegable.
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.
ws://localhost:3000/ws/a2a
Se abre desde JavaScript o desde un proceso agente. No es una pagina navegable.
Todo comando viaja como JSON con un campo obligatorio type. El servidor valida el payload antes de ejecutar.
Despues de cada comando, el servidor publica { "type": "state" } a todas las pantallas conectadas.
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.
{
"_id": "ObjectId(...)",
"userId": "user-001",
"email": "demo@local",
"name": "Usuario demo",
"token": "tok_demo_123",
"active": true
}
MONGODB_URI=mongodb://localhost:27017 MONGODB_DB=a2a MONGODB_USERS_COLLECTION=usuarios MONGODB_AGENTS_COLLECTION=agentes AUTH_TOKEN_HEADER=x-a2a-token
| 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.
ws://localhost:3000/ws/a2a.x-a2a-token: tok_demo_123.type.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://.
{
"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
}
}
{
"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
}
}
{
"type": "a2a.directory.request",
"requester": "agent-backend",
"mode": "connected"
}
En el mensaje state, busca:
{
"directory": {
"connected": [
{
"agentId": "agent-frontend",
"connectionId": "addr_..."
}
]
}
}
Ese connectionId es la direccion temporal para escribirle a ese agente.
{
"type": "a2a.message.direct",
"from": "agent-backend",
"toAddress": "addr_pega_aqui_la_direccion",
"text": "Necesito que revises la estructura visual de una plataforma academica."
}
{
"type": "a2a.decision.advise",
"requester": "agent-backend",
"project": "Crear una plataforma academica con API, dashboard, cursos, usuarios y reportes."
}
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.
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()));
});
| 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. |
{
"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
}
}
{
"type": "a2a.resource.deliver",
"target": "agent-a",
"resource": {
"kind": "json",
"name": "brief-academico",
"content": "{ \"pantallas\": [\"login\", \"cursos\"] }",
"metadata": {
"source": "usuario"
}
}
}
{
"type": "a2a.directory.request",
"requester": "agent-backend",
"mode": "connected"
}
{
"type": "a2a.message.direct",
"from": "agent-backend",
"toAddress": "addr_7f4f...",
"text": "Necesito que revises la propuesta frontend."
}
{
"type": "a2a.decision.advise",
"requester": "agent-backend",
"project": "Construir una plataforma academica con backend, frontend y reportes."
}
{
"type": "a2a.processing.start",
"target": "agent-a",
"task": "Analiza el recurso recibido y propone estructura backend."
}
{
"type": "a2a.agent.free",
"target": "agent-a",
"note": "Termine mi tarea actual y puedo recibir otra asignacion."
}
| 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. |
state a todos los HTML abiertos.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.agent.start: cada agente se registra y recibe una direccion unica connectionId.a2a.directory.request: cualquier agente pide conectados o disponibles.a2a.decision.advise: un agente consulta que otros agentes conviene usar para el proyecto.a2a.message.direct: el agente escribe a otro usando su direccion temporal.a2a.resource.deliver: el servidor entrega elementos o recursos al agente destino.a2a.processing.start: el agente empieza a procesar.a2a.processing.finish: el agente registra resultado del procesamiento.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.