Docs · Protocolos
Agente A2A
O ShvIA pode responder a outros agentes pelo protocolo Agent2Agent (A2A): outro agente envia uma pergunta e recebe uma resposta.
O que é#
Uma porta estreita. Um par envia texto; o ShvIA responde com um modelo que roda na infraestrutura do próprio operador. O modelo não recebe ferramentas, nem base de conhecimento, nem memória, nem anexos, e o par não pode escolher o modelo. Ele recebe a pergunta, as mensagens anteriores do mesmo contexto, as instruções-base da própria instalação e um breve prefácio que nomeia o par. Responde uma vez e de forma síncrona: não há streaming nem notificação push.
O turno roda como o administrador que registrou o par, e conta na cota desse administrador. A troca é guardada: cada contexto vira uma conversa na conta desse administrador, com o texto dos dois lados, e o administrador pode lê-la. Não envie nada que você não gostaria que ele lesse.
O cartão do agente#
GET/.well-known/agent-card.json#
/.well-known/agent.json devolve o mesmo cartão. Não exige autenticação.
{
"name": "ShvIA",
"description": "…",
"url": "https://ai.shvia.org/a2a/v1",
"protocolVersion": "1.0",
"supportedInterfaces": [{ "url": "https://ai.shvia.org/a2a/v1", "protocolBinding": "JSONRPC", "protocolVersion": "1.0" }],
"capabilities": { "streaming": false, "pushNotifications": false, "stateTransitionHistory": false, "extendedAgentCard": false },
"securitySchemes": { "bearer": { "httpAuthSecurityScheme": { "scheme": "bearer" } } },
"securityRequirements": [{ "schemes": { "bearer": { "list": [] } } }],
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
"skills": []
}O cartão acima está encurtado. Com um token de par válido, ele também lista a única skill, perguntar, e a versão do gateway.
Autenticação#
Envie o token do par como Authorization: Bearer shvia_a2a_…. O header X-API-Key não é aceito, e uma chave de API normal não abre esta porta: um token de par abre /a2a/v1 e mais nada.
Um token ausente, errado ou desligado devolve 401 com o código nao_autenticado. Cada par tem um teto de chamadas por minuto, 30 por padrão, definido pelo administrador. Acima dele, a chamada devolve 429 com limite_de_requisicoes e Retry-After. Há também um teto de 120 requisições por minuto por endereço no cartão e no endpoint, e acima dele a resposta é o simples {"message": "Too Many Attempts."}.
POST/a2a/v1#
Um endpoint JSON-RPC 2.0. Ele recebe um objeto de requisição por vez e responde a toda requisição, até a que não tem id.
| Método | Resultado |
|---|---|
SendMessage (ou message/send) | roda o modelo e devolve {"task": …} |
GetTask (ou tasks/get) | devolve uma tarefa que este par criou. As tarefas são guardadas por 24 horas |
CancelTask (ou tasks/cancel) | sempre falha: as tarefas terminam antes de você poder cancelá-las |
| métodos de streaming, de assinatura, de listagem e de push | não suportados, erro -32004 |
{
"jsonrpc": "2.0",
"id": "r1",
"method": "SendMessage",
"params": {
"message": {
"role": "ROLE_USER",
"messageId": "m-1",
"parts": [{ "text": "What is the capital of Bahia?", "mediaType": "text/plain" }]
}
}
}{
"jsonrpc": "2.0",
"id": "r1",
"result": {
"task": {
"id": "task-3f2a9c1b7d4e5a60",
"contextId": "ctx-0a1b2c3d4e5f6071",
"status": {
"state": "TASK_STATE_COMPLETED",
"timestamp": "2026-10-10T12:00:00.000Z",
"message": { "role": "ROLE_AGENT", "parts": [{ "text": "Salvador.", "mediaType": "text/plain" }], "messageId": "…", "contextId": "ctx-0a1b2c3d4e5f6071", "taskId": "task-3f2a9c1b7d4e5a60" }
},
"artifacts": [{ "artifactId": "…", "parts": [{ "text": "Salvador.", "mediaType": "text/plain" }] }]
}
}
}A mensagem#
- As partes com um
textsão unidas com quebras de linha. As partes comdataviram texto JSON compacto. As partes de arquivo e de URL são ignoradas. Uma mensagem sem nenhum texto é recusada com-32005. contextIdé opcional, de 1 a 128 caracteres entre letras, dígitos e._:-. Envie o mesmo para continuar uma conversa: as últimas 20 mensagens, cerca de 10 trocas, são reenviadas. Sem um, o servidor inventa um.- O texto acima de 65536 bytes é cortado, com uma marca no final.
Estados da tarefa#
| Estado | Significado |
|---|---|
TASK_STATE_COMPLETED | respondida. O texto está em status.message e em artifacts |
TASK_STATE_REJECTED | o administrador por trás do par não pode usar o modelo que responde, ou esgotou um limite de tokens. O motivo está em status.message |
TASK_STATE_FAILED | o modelo não conseguiu responder. Tente de novo |
Uma tarefa nunca fica em WORKING nem em SUBMITTED: a chamada é síncrona.
Erros#
Os erros de requisição são erros JSON-RPC dentro de um HTTP 200: -32700 não é JSON, -32600 uma requisição ruim ou um lote, -32601 um método desconhecido, -32602 parâmetros ruins, -32603 uma falha interna (por exemplo, nenhum modelo on-premises disponível), -32001 uma tarefa desconhecida, -32002 uma tarefa que não pode ser cancelada, -32004 uma operação não suportada e -32005 uma mensagem sem texto.