Saltar al contenido principal

Referencia del protocolo AG-UI

Esta página describe la interfaz HTTP/SSE de iac-code agui y las extensiones de iac-code dentro del envelope AG-UI estándar. Consulte antes la descripción general y los primeros pasos.

Endpoints HTTP

Método y rutaUso
GET /healthSalud y versiones
POST /Enviar RunAgentInput y recibir SSE
POST /extensions/iac-code/v1/executions/{executionId}/cancelExtensión de cancelación

Use JSON y solicite SSE:

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

Con IAC_CODE_AGUI_AUTH_TOKEN, añada Authorization: Bearer <token>. Accept-Language actúa como idioma alternativo; forwardedProps.iacCode.preferredLanguage tiene prioridad y se reenvía a A2A.

RunAgentInput

{
"threadId": "8473547e-c8ed-4aef-a84c-603a6a8d42da",
"runId": "32c263f2-b0b0-42ac-905c-524a0a9bb652",
"state": {},
"messages": [{"id": "message-1", "role": "user", "content": "Crea una plantilla de VPC"}],
"tools": [],
"context": [],
"forwardedProps": {"iacCode": {
"schemaVersion": 1,
"rosInvocationId": "invocation-1",
"cwd": "/workspace/session-1",
"runMode": "normal"
}}
}
Campo estándarRequisito y comportamiento
threadIdObligatorio y estable durante la conversación
runIdObligatorio y único por solicitud HTTP/SSE
parentRunIdOpcional; se copia a RUN_STARTED
stateObligatorio; no es el estado del runtime de iac-code
messagesObligatorio; un run nuevo usa el último mensaje de usuario
toolsObligatorio y vacío; no admite herramientas del cliente
contextObligatorio; actualmente no se convierte en contexto del prompt
forwardedPropsObligatorio con la extensión iacCode
resumeRespuestas a todos los Interrupt pendientes

Los mensajes admiten texto e imágenes base64 en línea. No se admiten URL remotas, audio, vídeo, documentos ni binarios genéricos. Límites: 8 MiB por imagen, 10 MiB en total y 12 MiB por solicitud.

forwardedProps.iacCode

El schema es estricto y rechaza campos desconocidos.

CampoTipoObligatorioUso
schemaVersion1Versión de extensión
rosInvocationIdstringIdentidad de la ejecución, máximo 256 caracteres
cwdstringWorkspace absoluto
model / llmApiKeystringNoModelo y clave LLM por solicitud
llmHeaders / llm_headersobjetoNoHeaders HTTP adicionales de string a string para las llamadas al proveedor LLM
thinking.enabled/effort/budgetboolean/string/entero positivoNoOpciones de thinking
userId / channelstringNoIdentidad y canal del llamante
preferredLanguagestringNoIdioma visible, por ejemplo es
candidatePresentationstandard / richNoPresentación de candidatos
runModenormal / pipelineNoModo de ejecución
pipelineNamestringNoNombre del Pipeline
cleanupOnlybooleanNoEjecutar solo limpieza
alibabaCloud.accessKeyIdstringNoAccessKey ID temporal
alibabaCloud.accessKeySecretstringNoAccessKey Secret temporal
alibabaCloud.securityTokenstringNoToken STS temporal
alibabaCloud.regionIdstringNoRegión predeterminada

llmHeaders sigue las reglas de vinculación al contexto A2A de metadata.iac_code.llm_headers: una vez enviado, las solicitudes posteriores del mismo thread AG-UI heredan los headers cuando se omite el campo. Un nuevo mapa reemplaza toda la vinculación y {} la borra. Como los valores pueden contener credenciales, el adaptador no los persiste; el llamante debe volver a enviarlos tras reiniciar el proceso A2A local.

El run inicial y sus Resume conservan el mismo rosInvocationId. Un turno normal posterior puede usar otro. El mismo threadId queda vinculado al primer cwd y userId.

SSE y eventos estándar

Tras 15 segundos sin eventos, el servidor envía : heartbeat. Es un comentario SSE, no un evento CUSTOM.

SeñalEvento AG-UI
Solicitud aceptadaRUN_STARTED
TextoTEXT_MESSAGE_*
RazonamientoREASONING_*
Herramienta y argumentosTOOL_CALL_START/ARGS/END
ResultadoTOOL_CALL_RESULT
Paso de PipelineSTEP_STARTED/STEP_FINISHED
Snapshot de recuperaciónACTIVITY_SNAPSHOT
Éxito o espera de entradaRUN_FINISHED con outcome success o interrupt
ErrorRUN_ERROR

RUN_FINISHED finaliza un run, no necesariamente el Pipeline. Los Interrupt producen runs nuevos. Antes de terminar por Interrupt se cierran los spans abiertos y el nuevo run reabre los pasos duraderos activos; no indica ejecución en orden inverso.

Eventos personalizados

  • iac-code.session.v1: relaciones de thread, execution, context, task y session; executionId permite cancelar.
  • iac-code.artifact.v1: proyección de artifacts A2A.
  • iac-code.tool-progress.v1: progreso intermedio sin equivalente estándar.
  • iac-code.pipeline.v1: datos útiles del Pipeline sin equivalente estándar.

Tipos de Pipeline admitidos:

  • pipeline_started, pipeline_resumed, pipeline_completed, pipeline_error, pipeline_warning, backup_blocked;
  • candidate_started, candidate_completed, candidate_failed, candidate_interrupted, candidate_restart_requested, candidate_selected, candidate_detail_shown, candidate_step_failed;
  • sub_pipeline_started, sub_pipeline_completed, sub_step_failed, step_failed;
  • stack_progress, stack_instances_progress, stack_current_changed, cleanup_started, cleanup_progress, cleanup_completed, cleanup_failed;
  • rollback_triggered, rollback_completed;
  • context_compaction_started, context_compacted, context_compaction_failed, fields_marked_stale;
  • diagram_shown, mcp_status, tool_progress.

text_delta, thinking_delta, tool_started/tool_result, usage y el ciclo de pasos ya tienen eventos estándar y no se duplican como CUSTOM. Deduzca repeticiones por eventId o sequence.

Interrupt y Resume

Cada Interrupt contiene id, reason, message, responseSchema, un toolCallId opcional y metadata descriptiva. La autorización suele aceptar {"decision":"allow_once"} o {"decision":"deny"}. La UI debe respetar el schema en vez de deducir la respuesta solo a partir de reason.

El adaptador no impone un plazo al Interrupt. Un Interrupt pendiente puede reanudarse hasta que A2A resuelva, cancele o termine la tarea; A2A es el único responsable del ciclo de vida de ejecución y recuperación.

Resume es otra solicitud con el mismo threadId, un runId nuevo y el mismo rosInvocationId:

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

Debe responder exactamente una vez a todos los Interrupt pendientes. resolved exige un payload válido; cancelled cancela y equivale a deny para permisos. Un error de schema genera RUN_ERROR y mantiene el Interrupt disponible. Repetir una respuesta aceptada no vuelve a ejecutar la herramienta.

Identidades y cancelación

Cada solicitud usa un runId único dentro del threadId; un Resume también es un run nuevo. La idempotencia se limita a (threadId, runId).

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

Responde cancelled, already_terminal o EXECUTION_NOT_FOUND. La cancelación borra los Interrupt pendientes.

Persistencia, desconexión y errores

El estado se guarda en <config-dir>/agui/threads/<thread-key>.json. Contiene relaciones, identidades, posiciones del Pipeline, Interrupt e idempotencia; carga solo el thread solicitado y sustituye atómicamente un archivo pequeño. No almacena claves LLM, secretos de AccessKey, STS token, texto de conversación ni artifacts. A2A gestiona su propia persistencia; consulte su documentación.

Un run terminado con Interrupt ya no depende de su SSE; desconectar un run normal activo cancela la tarea A2A.

Antes de SSE, los errores usan JSON HTTP; durante la ejecución usan RUN_ERROR. Los códigos principales son INVALID_INPUT, DUPLICATE_RUN_ID, RUN_ID_CONFLICT, THREAD_BUSY, THREAD_BINDING_CONFLICT, RESUME_REQUIRED, INCOMPLETE_RESUME, UNKNOWN_INTERRUPT, RESUME_PAYLOAD_INVALID, RESUME_ALREADY_APPLIED, EXECUTION_LOST, STATE_PERSISTENCE_FAILED, A2A_UNAVAILABLE, A2A_PROTOCOL_ERROR, A2A_EXECUTION_FAILED y CANCELLED.

Las escrituras necesarias para la recuperación fallan de forma cerrada: el adaptador no anuncia un estado recuperable antes de guardarlo y cancela la tarea A2A cuando sea necesario.