Pular para o conteudo principal

Referência do protocolo AG-UI

Esta página descreve a interface HTTP/SSE exposta por iac-code agui e os campos de extensão do iac-code transportados em envelopes AG-UI padrão. Consulte primeiro a visão geral e os primeiros passos.

Endpoints HTTP

Método e caminhoFinalidade
GET /healthIntegridade do serviço e versões do protocolo
POST /Enviar RunAgentInput e receber um fluxo de eventos SSE
POST /extensions/iac-code/v1/executions/{executionId}/cancelExtensão de cancelamento com namespace

O corpo de POST / deve usar JSON, e clientes devem solicitar SSE:

Content-Type: application/json
Accept: text/event-stream

Quando IAC_CODE_AGUI_AUTH_TOKEN estiver configurado, solicitações protegidas também exigem:

Authorization: Bearer <token>

Use o cabeçalho padrão Accept-Language como alternativa para o idioma das mensagens de erro. forwardedProps.iacCode.preferredLanguage tem prioridade e também é encaminhado ao runtime A2A.

RunAgentInput

Exemplo mínimo de execução normal:

{
"threadId": "8473547e-c8ed-4aef-a84c-603a6a8d42da",
"runId": "32c263f2-b0b0-42ac-905c-524a0a9bb652",
"state": {},
"messages": [
{"id": "message-1", "role": "user", "content": "Crie um modelo de VPC"}
],
"tools": [],
"context": [],
"forwardedProps": {
"iacCode": {
"schemaVersion": 1,
"rosInvocationId": "invocation-1",
"cwd": "/workspace/session-1",
"runMode": "normal"
}
}
}

Campos padrão

CampoRequisitoComportamento do iac-code
threadIdString não vazia obrigatóriaIdentidade estável da conversa, mapeada para um contexto A2A e uma sessão do iac-code
runIdString não vazia obrigatóriaUma execução HTTP/SSE; não pode ser reutilizada no thread
parentRunIdOpcionalCopiado para RUN_STARTED
stateObrigatórioMantido no envelope padrão, mas não usado como estado de runtime do iac-code
messagesObrigatórioNova execução usa a última mensagem do usuário; uma retomada não precisa adicionar outra
toolsObrigatório e vazioFerramentas definidas pelo cliente não são compatíveis
contextObrigatórioMantido no envelope; ainda não convertido em contexto do prompt
forwardedPropsObrigatórioDeve conter a extensão iacCode
resumePara retomadaUma resposta para cada interrupção pendente

Mensagens do usuário aceitam strings e partes text e image com fontes data base64 incorporadas. URLs de imagem remota, áudio, vídeo, documentos e binários genéricos não são compatíveis. Uma imagem decodificada é limitada a 8 MiB, todas as imagens a 10 MiB e a solicitação HTTP completa a 12 MiB.

forwardedProps.iacCode

O esquema é estrito; campos desconhecidos são rejeitados.

CampoTipoObrigatórioSignificado
schemaVersion1SimVersão da extensão do iac-code
rosInvocationIdstringSimIdentidade do chamador da execução atual, até 256 caracteres
cwdstringSimCaminho absoluto do workspace
modelstringNãoSubstituição do modelo para a solicitação
llmApiKeystringNãoChave do provedor LLM para a solicitação
llmHeaders / llm_headersobjetoNãoHeaders HTTP adicionais de string para string nas chamadas ao provedor LLM
thinking.enabledbooleanoNãoSolicitar saída de raciocínio
thinking.effortstringNãoEsforço de raciocínio específico do provedor
thinking.budgetinteiro positivoNãoOrçamento de raciocínio específico do provedor
userIdstringNãoIdentidade de telemetria e vínculo do chamador
channelstringNãoMetadados do canal chamador
preferredLanguagestringNãoIdioma de exibição local à solicitação, como pt
candidatePresentationstandard ou richNãoApresentação dos candidatos do Pipeline
runModenormal ou pipelineNãoModo de execução; caso contrário, escolhido pelo A2A
pipelineNamestringNãoNome do Pipeline, por exemplo selling
cleanupOnlybooleanoNãoSolicitar apenas o caminho de limpeza do Pipeline
alibabaCloud.accessKeyIdstringNãoAccessKey ID local à solicitação
alibabaCloud.accessKeySecretstringNãoSegredo AccessKey local à solicitação
alibabaCloud.securityTokenstringNãoToken STS local à solicitação
alibabaCloud.regionIdstringNãoRegião padrão local à solicitação

llmHeaders segue as regras de vínculo ao contexto A2A de metadata.iac_code.llm_headers: depois de informado, as solicitações posteriores do mesmo thread AG-UI herdam os headers quando o campo é omitido. Um novo mapa substitui todo o vínculo, e {} o limpa. Como os valores podem conter credenciais, o adaptador não os persiste; o chamador deve enviá-los novamente após a reinicialização do processo A2A local.

A execução inicial e suas retomadas devem manter o mesmo rosInvocationId. Um turno normal posterior pode usar um novo valor. O cancelamento deve usar o valor da execução atual.

O threadId é vinculado aos cwd e userId da primeira solicitação; solicitações posteriores não podem mover o mesmo thread para outro workspace ou chamador.

SSE e heartbeat

Cada evento AG-UI é emitido como um registro SSE data:. Após 15 segundos sem eventos, o servidor emite:

: heartbeat

Esse é um comentário SSE, não um evento AG-UI CUSTOM. Clientes compatíveis o ignoram enquanto ele mantém a conexão HTTP ativa.

Mapeamento de eventos padrão

Sinal A2A/iac-codeSaída AG-UI
Solicitação aceitaRUN_STARTED
Texto do agenteTEXT_MESSAGE_START/CONTENT/END
Raciocínio brutoREASONING_START, REASONING_MESSAGE_*, REASONING_END
Início e argumentos da ferramentaTOOL_CALL_START/ARGS/END
Resultado da ferramentaTOOL_CALL_RESULT
Ciclo de vida da etapa do PipelineSTEP_STARTED/STEP_FINISHED
Snapshot de recuperação do PipelineACTIVITY_SNAPSHOT
Conclusão normalRUN_FINISHED com outcome.type = "success"
Entrada do usuário necessáriaRUN_FINISHED com outcome.type = "interrupt"
Erro do adaptador ou A2ARUN_ERROR

RUN_FINISHED encerra uma execução AG-UI, não necessariamente todo o Pipeline. Um Pipeline interrompido várias vezes possui várias execuções, cada uma com seus próprios RUN_STARTED e RUN_FINISHED. A conclusão funcional do Pipeline é representada por pipeline_completed, pipeline_error e eventos relacionados.

Para manter os spans AG-UI equilibrados, o adaptador fecha spans abertos de mensagem, raciocínio, ferramenta e etapa antes de uma interrupção encerrar a execução. A retomada reabre etapas duráveis do Pipeline que ainda estão ativas. Por isso, a inspeção de eventos brutos pode mostrar a mesma etapa funcional encerrando em uma execução e reabrindo na seguinte; isso não significa execução invertida.

Eventos personalizados do iac-code

iac-code.session.v1

Expõe o mapeamento atual entre adaptador e A2A, incluindo threadId, aguiRunId, executionId, contextId, taskId, rosInvocationId e sessionId. Use executionId na extensão de cancelamento. Clientes genéricos podem ignorar esse evento.

iac-code.artifact.v1

Transporta uma projeção estruturada de um artefato de tarefa A2A para visualização, download ou diagnóstico opcionais.

iac-code.tool-progress.v1

Transporta progresso intermediário de ferramenta sem equivalente padrão. Início, argumentos e resultado final continuam como eventos padrão TOOL_CALL_* e não são duplicados aqui.

iac-code.pipeline.v1

Somente informações úteis do Pipeline sem equivalente padrão completo são emitidas. Valores atuais de eventType:

  • Pipeline: pipeline_started, pipeline_resumed, pipeline_completed, pipeline_error, pipeline_warning, backup_blocked;
  • candidatos: candidate_started, candidate_completed, candidate_failed, candidate_interrupted, candidate_restart_requested, candidate_selected, candidate_detail_shown, candidate_step_failed;
  • sub-Pipelines e erros de etapa: sub_pipeline_started, sub_pipeline_completed, sub_step_failed, step_failed;
  • stacks e limpeza: stack_progress, stack_instances_progress, stack_current_changed, cleanup_started, cleanup_progress, cleanup_completed, cleanup_failed;
  • rollback: rollback_triggered, rollback_completed;
  • contexto: context_compaction_started, context_compacted, context_compaction_failed, fields_marked_stale;
  • apresentação e ferramentas: diagram_shown, mcp_status, tool_progress.

Sinais com mapeamentos padrão não são duplicados como CUSTOM: text_delta se torna TEXT_MESSAGE_*, thinking_delta se torna REASONING_*, tool_started/tool_result se tornam TOOL_CALL_*, usage se torna RUN_FINISHED.usage e ciclos de etapas se tornam STEP_*.

Clientes devem eliminar eventos de Pipeline repetidos usando (name, value.eventId) ou a sequência do Pipeline e tolerar eventos personalizados com namespace desconhecidos.

Interrupção

Uma execução que requer entrada termina com RUN_FINISHED.outcome.type = "interrupt". Cada interrupção contém:

  • id e reason;
  • uma message para o usuário;
  • um toolCallId opcional;
  • um responseSchema JSON;
  • metadados como title, purpose, safeSummary, options e toolName.

O adaptador não impõe prazo ao Interrupt. Um Interrupt pendente continua retomável até que o A2A resolva, cancele ou encerre a tarefa; somente o A2A controla o ciclo de vida da execução e da recuperação.

Para uma solicitação de permissão, o esquema normalmente aceita:

{"decision": "allow_once"}

ou:

{"decision": "deny"}

Renderize message, responseSchema e os metadados descritivos em vez de inferir a interface apenas a partir de reason. Perguntas e seleção de opções podem usar esquemas diferentes.

Retomada

Uma retomada é um novo POST / com o mesmo threadId, um novo runId, o mesmo rosInvocationId e uma entrada por interrupção pendente:

{
"resume": [
{
"interruptId": "permission-1",
"status": "resolved",
"payload": {"decision": "allow_once"}
}
]
}

Regras:

  • cada interrupção pendente deve ser respondida exatamente uma vez;
  • IDs duplicados e desconhecidos são rejeitados;
  • resolved exige um payload compatível com o esquema;
  • cancelled encerra a interrupção e corresponde a deny para permissões;
  • o estado pendente durável só é removido depois que o A2A aceita a resposta;
  • erros de esquema produzem RUN_ERROR, mantendo a interrupção disponível para nova tentativa;
  • repetir uma resposta já aceita não executa a ferramenta novamente.

Antes de aplicar uma retomada, o adaptador pode solicitar ao A2A que restaure a sessão do iac-code, verifica as identidades de tarefa e contexto A2A e recupera eventos de Pipeline ausentes.

Turnos e identidades

threadId (conversa estável)
├─ runId-1 (turno do usuário)
├─ runId-2 (retomada de interrupção)
├─ runId-3 (outra retomada)
└─ runId-4 (próxima mensagem normal)

Cada solicitação HTTP/SSE usa um runId exclusivo. A retomada é uma nova execução. Após um turno normal, a próxima mensagem cria uma nova execução e reutiliza a sessão do iac-code do thread. A idempotência está no escopo de (threadId, runId).

Extensão de cancelamento

POST /extensions/iac-code/v1/executions/<executionId>/cancel
Content-Type: application/json
{"threadId": "thread-1", "rosInvocationId": "invocation-1"}

Os resultados possíveis são cancelled, already_terminal ou HTTP 404 com EXECUTION_NOT_FOUND. O cancelamento limpa interrupções pendentes e não altera os formatos padrão dos eventos AG-UI.

Persistência e recuperação

O estado do adaptador usa por padrão:

<config-dir>/agui/threads/<thread-key>.json

Cada arquivo contém o vínculo entre thread, contexto e workspace, identidades de sessão, tarefa e execução, posições de recuperação do Pipeline, interrupções pendentes e dados de idempotência. O adaptador carrega sob demanda apenas o thread solicitado e substitui atomicamente somente o pequeno arquivo desse thread.

Chaves de LLM, segredos AccessKey e tokens STS nunca são armazenados. Esse é um diretório de mapeamentos do adaptador, não de conversas ou artefatos de execução. O A2A gerencia sua própria persistência de sessões e tarefas; consulte a documentação do A2A.

Desconexões

  • Uma execução concluída com segurança por uma interrupção deixa de depender da conexão SSE.
  • Uma retomada cria uma nova conexão SSE.
  • Desconectar uma execução normal ativa faz o adaptador cancelar a tarefa A2A.
  • Desconectar após uma interrupção não apaga seu estado persistente de recuperação.

Erros

Erros anteriores ao início do SSE usam um envelope JSON HTTP. Erros durante a execução usam eventos padrão RUN_ERROR.

CódigoSignificado
INVALID_INPUTEnvelope, extensão, conteúdo de mensagem ou workspace inválido
DUPLICATE_RUN_IDO mesmo digest de solicitação usou um run ID existente
RUN_ID_CONFLICTUma solicitação diferente reutilizou um run ID existente
THREAD_BUSYO thread já tem uma execução ativa
THREAD_BINDING_CONFLICTWorkspace ou chamador conflita com o vínculo do thread
RESUME_REQUIREDO thread aguarda respostas de interrupção
INCOMPLETE_RESUMEInterrupções pendentes ausentes ou IDs duplicados
UNKNOWN_INTERRUPTA retomada referencia uma interrupção desconhecida
RESUME_PAYLOAD_INVALIDPayload ausente ou incompatível com o esquema
RESUME_ALREADY_APPLIEDA resposta já foi aplicada ou conflita com ela
EXECUTION_LOSTNão foi possível recuperar o adaptador, a tarefa A2A ou a sessão do iac-code
STATE_PERSISTENCE_FAILEDO estado crítico para recuperação não pôde ser persistido
A2A_UNAVAILABLEO serviço local de execução A2A está indisponível
A2A_PROTOCOL_ERRORIdentidade de tarefa, contexto ou sessão conflita com o mapeamento
A2A_EXECUTION_FAILEDA tarefa A2A terminou com falha
CANCELLEDA execução foi cancelada

Gravações críticas para recuperação falham de forma segura. O adaptador não anuncia uma tarefa, sessão ou interrupção recuperável antes que seu mapeamento esteja persistido, e cancela a tarefa A2A correspondente quando necessário.