FullAgenticStack Intent-based Healing Patterns: Interactive-Intent-Healing
Source: Dev.to
Nova camada: Interactive Intent-Healing (IIH)
O que ela faz
Quando o sistema:
- captura um erro,
- tenta auto‑healing,
- não consegue corrigir,
ele emite um evento pedindo intervenção humana, recebe um valor novo (ou um patch) e aplica diretamente no payload para retentar o passo que falhou.
Isso corresponde à família conceitual de “pausar execução e retomar com input externo” (human‑in‑the‑loop) usada por frameworks modernos via interrupt/resume (ver LangChain Docs). No contexto do IIH, o HITL torna‑se Human‑in‑the‑Healing‑Loop.
Padronização como JSON Patch (RFC 6902)
- explícito
- auditável
- validável com whitelist de paths
- gera evidência versionável (RFC Editor)
Exemplo de request de intervenção (interactive_healing_request)
{
"type": "interactive_healing_request",
"sessionId": "aon_s_01H...",
"requestId": "req_01H...",
"error": {
"code": "schema_validation_failed",
"message": "field userId must be uuidv4"
},
"payloadSnapshotHash": "sha256:...",
"suggestedPatches": [
{ "op": "replace", "path": "/userId", "value": "uuidv4_placeholder" }
],
"allowedPatchPaths": ["/userId", "/items/*/quantity"],
"timeoutMs": 60000
}
Resposta do desenvolvedor (interactive_healing_response)
{
"type": "interactive_healing_response",
"sessionId": "aon_s_01H...",
"requestId": "req_01H...",
"patch": [
{ "op": "replace", "path": "/userId", "value": "7b0b2d32-9db7-4aa7-a7e4-7f8b1e0adf7c" }
],
"reason": "ID veio do CRM legado; normalizei para uuid"
}
Fluxo resumido
- fail → auto‑healing tenta N estratégias
- falhou → emite
interactive_healing_request(atétimeoutMs) - Se chegar um patch válido → aplica, emite
interactive_healing_appliede faz retry - Se não houver patch ou for negado → emite erro terminal (ou “pending” para async)
- development ou staging: bloquear aguardando o dev.
- produção: emitir o evento, gerar um “ticket de healing” e falhar normalmente (para não segurar conexão e recursos).
- Canal WebSocket único; devolve no primeiro HTTP response.
Conceito
Sessão e rotas iniciais
No início de um request AON (qualquer modo) é criado um sessionId e computadas as rotas:
- WebSocket:
wss://host/aon/ws/?token= - SSE:
https://host/aon/sse/?token=
Interatividade
- SSE – telemetria unidirecional (server → client) – ideal para observação.
- WebSocket – bidirecional – permite que o dev responda com o patch (IIH).
Logs para o frontend
- NDJSON – o próprio response quando
Accept: application/x-ndjson.
Logs para o backend
Modo JSON (black box)
Sem stream, devolve cabeçalhos:
X-AON-WS: /aon/ws/?token=...
X-AON-SSE: /aon/sse/?token=...
ou corpo com campo _aon:
{
"data": { "...": "..." },
"_aon": {
"sessionId": "aon_s_01H...",
"ws": "/aon/ws/aon_s_01H...?token=...",
"sse": "/aon/sse/aon_s_01H...?token=..."
}
}
Modo NDJSON (glass box)
Primeira linha do stream:
{"type":"channels","sessionId":"aon_s_01H...","ws":"/aon/ws/...","sse":"/aon/sse/...","timestamp":...}
O SSE espelha exatamente o NDJSON:
event:
data:
id:
Exemplo:
event: healing
data: {"type":"healing","severity":"medium","action":"recover_db_connection",...}
AON Event Hub interno
emit(event) é chamado por middleware/healer; o hub distribui para:
NDJSONStreamWriter(quando o request for NDJSON)SSEsubscribers (porsessionId)WStopic (porsessionId)
Isso garante uma única fonte de verdade e se alinha ao mindset do OpenTelemetry, onde “eventos” são logs estruturados correlacionáveis.
- WS pode receber os mesmos eventos do SSE/NDJSON.
- IIH: WS é o canal ideal para o dev responder com o patch (bidirecional).
Estrutura de código (exemplo)
src/aon/
├── hub.ts # Event hub + session registry + buffer
├── sse.ts # handler /aon/sse/:sessionId
├── ndjson.ts # handler /aon/ndjson/:sessionId
├── ws.ts # handler /aon/ws/:sessionId (adapter)
├── iih.ts # Interactive Intent Healing
# IIH: request/await/patch/apply/retry
│ types.ts
Eventos suportados
channelsinteractive_healing_requestinteractive_healing_appliedinteractive_healing_timeout(opcional)
Se o dev abrir SSE após o início do request, ele pode perder eventos. Soluções:
- Ring buffer em memória por
sessionId(TTL curto, ex. 5 min) - Redis Streams para escalabilidade horizontal
Considerações de segurança & observabilidade
sessionIdnão é segredo; use OAuth 2.1 com JWT e DPoP.- UUID Verifiable para identidade de agentes.
- Signal e2e no WebSocket (opcional no SSE e NDJSON).
- traceId / spanId / requestId / sessionId obrigatórios nos eventos – permite navegação perfeita e correlação (padrão OpenTelemetry).
Referências rápidas
- AON – Adaptive Observability Negotiation (NDJSON, healing, eventos)
- Human‑in‑the‑loop via “interrupt/resume” (LangChain Docs)
- JSON Patch (RFC 6902) – RFC Editor
- SSE vs WebSocket – telemetria unidirecional vs bidirecional (Ably Realtime)
- Logs/eventos estruturados e correlação – OpenTelemetry