> ## Documentation Index
> Fetch the complete documentation index at: https://docs.evo-ai.co/llms.txt
> Use this file to discover all available pages before exploring further.

# A2A Protocol

> Integre agentes usando o protocolo Agent-to-Agent para comunicação padronizada entre agentes de IA

## Visão Geral

O **Agent-to-Agent Protocol (A2A)** é um protocolo padronizado desenvolvido pelo Google para permitir comunicação estruturada entre agentes de IA independentes. Utilizando JSON-RPC 2.0 sobre HTTP/HTTPS, o A2A facilita a interoperabilidade entre diferentes sistemas de agentes, permitindo que trabalhem em conjunto de forma eficiente.

<Note>
  **Protocolo Oficial**: O A2A é mantido pelo Google e está disponível em [google.github.io/A2A](https://google.github.io/A2A/specification/).
  O código fonte pode ser encontrado no [repositório GitHub](https://github.com/google/A2A).
</Note>

## Características Principais

<CardGroup cols={2}>
  <Card title="JSON-RPC 2.0" icon="code">
    Protocolo baseado em JSON-RPC 2.0 para comunicação estruturada e padronizada
  </Card>

  <Card title="Multi-turn" icon="comments">
    Suporte nativo a conversas com múltiplos turnos usando contextId
  </Card>

  <Card title="Upload de Arquivos" icon="upload">
    Transferência de arquivos via Base64 com suporte a diferentes tipos MIME
  </Card>

  <Card title="Streaming" icon="bolt">
    Comunicação assíncrona via Server-Sent Events (SSE) para respostas em tempo real
  </Card>
</CardGroup>

## Visão Geral Rápida

| Ponto-chave                 | Resumo                                                                                                                                                                                                       |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Objetivo**                | Padronizar a conversa entre agentes de IA (independentemente do fornecedor) usando JSON-RPC 2.0                                                                                                              |
| **Formato base**            | Cada chamada é um objeto JSON com `jsonrpc:"2.0"`, `id`, `method` e `params`                                                                                                                                 |
| **Métodos principais**      | `message/send` • `message/stream` • `tasks/get` • `tasks/cancel` • `tasks/pushNotificationConfig/{set\|get}` • `tasks/resubscribe` • `agent/authenticatedExtendedCard`                                       |
| **IDs obrigatórios**        | `messageId` (UUID v4) dentro de cada mensagem e `id`/`taskId`/`callId` para rastrear requisição e tarefa                                                                                                     |
| **Recursos de 1ª classe**   | Conversas multi-turn (`contextId`) • Upload de arquivos (`parts[]` tipo `file` com Base64 + MIME) • Notificações Push via `pushNotificationConfig` • Autenticação por `x-api-key` ou `Authorization: Bearer` |
| **Ciclo de vida da tarefa** | `submitted → working → completed / failed / canceled`, relatado em `result.status.state`                                                                                                                     |

## Métodos do Protocolo

### message/send (HTTP Síncrono)

O método principal para enviar mensagens de forma síncrona.

<AccordionGroup>
  <Accordion icon="paper-plane" title="Estrutura da Requisição">
    ```json theme={null}
    POST /api/v1/a2a/AGENT-ID
    Content-Type: application/json
    x-api-key: YOUR_API_KEY

    {
      "jsonrpc": "2.0",
      "id": "req-001",
      "method": "message/send",
      "params": {
        "message": {
          "role": "user",
          "parts": [{ "type": "text", "text": "Olá, quem é você?" }],
          "messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
        },
        "sessionId": "session-789",    // opcional, para multi-turn
        "id": "task-456"               // taskId opcional
      }
    }
    ```
  </Accordion>

  <Accordion icon="reply" title="Resposta Típica">
    ```json theme={null}
    {
      "jsonrpc": "2.0",
      "result": {
        "id": "task-456",
        "status": {
          "state": "completed",
          "message": {
            "role": "agent",
            "parts": [{ "type": "text", "text": "Sou um agente A2A pronto para ajudar!" }]
          }
        },
        "final": true
      },
      "id": "req-001"
    }
    ```
  </Accordion>
</AccordionGroup>

### message/stream (SSE Assíncrono)

Para comunicação em tempo real com streaming de respostas.

<AccordionGroup>
  <Accordion icon="bolt" title="Requisição Inicial">
    ```json theme={null}
    POST /api/v1/a2a/AGENT-ID
    Content-Type: application/json
    Accept: text/event-stream
    x-api-key: YOUR_API_KEY

    {
      "jsonrpc": "2.0",
      "id": "req-002",
      "method": "message/stream",
      "params": {
        "message": {
          "role": "user",
          "parts": [{ "type": "text", "text": "Gere um relatório detalhado" }],
          "messageId": "uuid-here"
        }
      }
    }
    ```
  </Accordion>

  <Accordion icon="wifi" title="Eventos SSE">
    ```
    data: {"jsonrpc":"2.0","id":"req-002",
           "result":{"id":"task-789",
                     "status":{"state":"working"},
                     "final":false}}

    data: {"jsonrpc":"2.0","id":"req-002",
           "result":{"id":"task-789",
                     "status":{"state":"completed",
                               "message":{"role":"agent",
                                          "parts":[{"type":"text","text":"Aqui está seu relatório..."}]}},
                     "final":true}}
    ```
  </Accordion>
</AccordionGroup>

## Exemplos de Implementação

### cURL

<CodeGroup>
  ```bash message/send theme={null}
  curl -X POST http://localhost:8000/api/v1/a2a/AGENT-ID \
    -H 'Content-Type: application/json' \
    -H 'x-api-key: YOUR_API_KEY' \
    -d '{
      "jsonrpc": "2.0",
      "id": "req-001",
      "method": "message/send",
      "params": {
        "message": {
          "role": "user",
          "parts": [{"type": "text", "text": "Olá!"}],
          "messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
        }
      }
    }'
  ```

  ```bash message/stream theme={null}
  curl -X POST http://localhost:8000/api/v1/a2a/AGENT-ID \
    -H 'Content-Type: application/json' \
    -H 'Accept: text/event-stream' \
    -H 'x-api-key: YOUR_API_KEY' \
    -d '{
      "jsonrpc": "2.0",
      "id": "req-002",
      "method": "message/stream",
      "params": {
        "message": {
          "role": "user",
          "parts": [{"type": "text", "text": "Streaming test"}],
          "messageId": "uuid-here"
        }
      }
    }'
  ```
</CodeGroup>

### JavaScript / Fetch

<CodeGroup>
  ```javascript message/send theme={null}
  const payload = {
    "jsonrpc": "2.0",
    "id": "req-001",
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"type": "text", "text": "Explique o protocolo A2A"}],
        "messageId": crypto.randomUUID()
      }
    }
  };

  const response = await fetch('/api/v1/a2a/AGENT-ID', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': 'YOUR_API_KEY'
    },
    body: JSON.stringify(payload)
  });

  const result = await response.json();
  console.log(result);
  ```

  ```javascript message/stream theme={null}
  const payload = {
    "jsonrpc": "2.0",
    "id": "req-002",
    "method": "message/stream",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"type": "text", "text": "Streaming response"}],
        "messageId": crypto.randomUUID()
      }
    }
  };

  const response = await fetch('/api/v1/a2a/AGENT-ID', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'text/event-stream',
      'x-api-key': 'YOUR_API_KEY'
    },
    body: JSON.stringify(payload)
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    
    const chunk = decoder.decode(value);
    const lines = chunk.split('\n');
    
    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = JSON.parse(line.slice(6));
        console.log(data);
        
        if (data.result?.final) {
          return; // Finalizar stream
        }
      }
    }
  }
  ```
</CodeGroup>

### Python

<CodeGroup>
  ```python message/send theme={null}
  import requests
  import uuid
  import json

  payload = {
      "jsonrpc": "2.0",
      "id": str(uuid.uuid4()),
      "method": "message/send",
      "params": {
          "message": {
              "role": "user",
              "parts": [{"type": "text", "text": "Explique o protocolo A2A"}],
              "messageId": str(uuid.uuid4())
          }
      }
  }

  response = requests.post(
      "http://localhost:8000/api/v1/a2a/AGENT-ID",
      headers={"x-api-key": "YOUR_API_KEY"},
      json=payload
  )

  print(json.dumps(response.json(), indent=2, ensure_ascii=False))
  ```

  ```python message/stream theme={null}
  import requests
  import uuid
  import json

  payload = {
      "jsonrpc": "2.0",
      "id": str(uuid.uuid4()),
      "method": "message/stream",
      "params": {
          "message": {
              "role": "user",
              "parts": [{"type": "text", "text": "Streaming response"}],
              "messageId": str(uuid.uuid4())
          }
      }
  }

  response = requests.post(
      "http://localhost:8000/api/v1/a2a/AGENT-ID",
      headers={
          "x-api-key": "YOUR_API_KEY",
          "Accept": "text/event-stream"
      },
      json=payload,
      stream=True
  )

  for line in response.iter_lines():
      if line:
          line_str = line.decode('utf-8')
          if line_str.startswith('data: '):
              data = json.loads(line_str[6:])
              print(json.dumps(data, indent=2, ensure_ascii=False))
              
              if data.get('result', {}).get('final'):
                  break
  ```
</CodeGroup>

## Upload de Arquivos

O protocolo A2A suporta upload de arquivos através do tipo `file` em `parts`:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": "req-003",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "type": "text",
          "text": "Analise esta imagem"
        },
        {
          "type": "file",
          "file": {
            "name": "imagem.png",
            "mimeType": "image/png",
            "bytes": "iVBORw0KGgoAAAANSUhEUgAAAAUA..." // Base64 sem cabeçalho
          }
        }
      ],
      "messageId": "uuid-here"
    }
  }
}
```

<Warning>
  **Formato Base64**: Os arquivos devem ser codificados em Base64 **sem** o cabeçalho `data:mime/type;base64,`.
  Apenas o conteúdo Base64 puro deve ser incluído no campo `bytes`.
</Warning>

## Conversas Multi-turn

Para manter contexto entre múltiplas mensagens, use o `contextId`:

<AccordionGroup>
  <Accordion icon="message" title="Primeira mensagem">
    ```json theme={null}
    {
      "jsonrpc": "2.0",
      "id": "req-001",
      "method": "message/send",
      "params": {
        "message": {
          "role": "user",
          "parts": [{"type": "text", "text": "Meu nome é João"}],
          "messageId": "msg-001"
        }
      }
    }
    ```

    **Resposta:**

    ```json theme={null}
    {
      "jsonrpc": "2.0",
      "result": {
        "id": "task-001",
        "contextId": "ctx-abc123", // Guardar este ID
        "status": {
          "state": "completed",
          "message": {
            "role": "agent",
            "parts": [{"type": "text", "text": "Olá João! Como posso ajudá-lo?"}]
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion icon="reply" title="Mensagem subsequente">
    ```json theme={null}
    {
      "jsonrpc": "2.0",
      "id": "req-002",
      "method": "message/send",
      "params": {
        "contextId": "ctx-abc123", // Usar o contextId anterior
        "message": {
          "role": "user",
          "parts": [{"type": "text", "text": "Qual é o meu nome?"}],
          "messageId": "msg-002"
        }
      }
    }
    ```

    **Resposta:**

    ```json theme={null}
    {
      "jsonrpc": "2.0",
      "result": {
        "id": "task-002",
        "contextId": "ctx-abc123",
        "status": {
          "state": "completed",
          "message": {
            "role": "agent",
            "parts": [{"type": "text", "text": "Seu nome é João!"}]
          }
        }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Estados da Tarefa

O protocolo A2A define estados específicos para o ciclo de vida das tarefas:

| Estado      | Descrição                             |
| ----------- | ------------------------------------- |
| `submitted` | Tarefa foi recebida e está na fila    |
| `working`   | Tarefa está sendo processada          |
| `completed` | Tarefa foi concluída com sucesso      |
| `failed`    | Tarefa falhou durante o processamento |
| `canceled`  | Tarefa foi cancelada pelo usuário     |

## Autenticação

O protocolo suporta diferentes métodos de autenticação:

<Tabs>
  <Tab title="API Key">
    ```http theme={null}
    x-api-key: YOUR_API_KEY
    ```
  </Tab>

  <Tab title="Bearer Token">
    ```http theme={null}
    Authorization: Bearer YOUR_TOKEN
    ```
  </Tab>
</Tabs>

## Dicas e Boas Práticas

<AccordionGroup>
  <Accordion icon="lightbulb" title="IDs únicos">
    * Use **UUID v4** para todos os IDs obrigatórios (`messageId`, `id`, etc.)
    * Mantenha consistência nos IDs para rastreamento adequado
  </Accordion>

  <Accordion icon="comments" title="Multi-turn">
    * Sempre guarde o `contextId` retornado para conversas contínuas
    * Envie o `contextId` em todas as mensagens subsequentes da mesma conversa
  </Accordion>

  <Accordion icon="file" title="Arquivos">
    * Use Base64 **sem cabeçalho** no campo `bytes`
    * Especifique sempre o `mimeType` correto
    * Considere o tamanho máximo suportado pelo servidor
  </Accordion>

  <Accordion icon="bolt" title="Streaming">
    * Trate eventos de ping (`: ping`) adequadamente
    * Feche a conexão `EventSource` quando `final: true`
    * Implemente tratamento de reconexão para robustez
  </Accordion>

  <Accordion icon="globe" title="CORS">
    * Configure CORS no servidor (`Access-Control-Allow-Origin: *`) para testes no navegador
    * Use headers apropriados para produção
  </Accordion>
</AccordionGroup>

## Recursos Adicionais

<CardGroup cols={2}>
  <Card title="Especificação Oficial" icon="book" href="https://google.github.io/A2A/specification/">
    Documentação completa do protocolo A2A mantida pelo Google
  </Card>

  <Card title="Repositório GitHub" icon="github" href="https://github.com/google/A2A">
    Código fonte, exemplos e issues do projeto A2A
  </Card>

  <Card title="Guia de Início Rápido" icon="rocket" href="/quickstart">
    Configure seu primeiro agente em menos de 2 minutos
  </Card>

  <Card title="Tipos de Agentes" icon="users" href="/agents/index">
    Explore diferentes tipos de agentes compatíveis com A2A
  </Card>
</CardGroup>

***

Com o protocolo A2A, você pode integrar rapidamente qualquer agente ou aplicação front-end ao ecossistema Evo AI, garantindo interoperabilidade e comunicação padronizada entre diferentes sistemas de agentes de IA.
