Referência

Eventos

Tipos de evento usados pelo event log de sessions, pelo stream SSE e por webhooks.

Eventos são ordenados por seq dentro de uma session. O mesmo evento pode ser lido no histórico e recebido no stream.

#Eventos ingeríveis

Seu backend pode postar estes eventos no endpoint de events da session:

TipoPayloadUso
user.message{ content, idempotencyKey? }Envia uma mensagem ou instrução do usuário.
user.interrupt{ idempotencyKey? }Solicita interrupção do trabalho atual.
user.custom_tool_result{ toolUseId, content, isError?, idempotencyKey? }Responde custom tool executada pelo cliente.
user.tool_confirmation{ toolUseId, decision, reason?, idempotencyKey? }Aprova ou nega tool que pediu confirmação.

content usa blocos de texto: [{ "type": "text", "text": "..." }].

#Eventos do agent

TipoQuando ocorre
agent.messageO agent produziu resposta textual.
agent.thinkingO provider expôs conteúdo de raciocínio apresentável.
agent.tool_useO agent solicitou uma built-in tool.
agent.tool_resultResultado de uma built-in tool.
agent.custom_tool_useO agent solicitou uma custom tool executada pelo seu backend.
agent.mcp_tools_listedTools MCP foram resolvidas para a session.
agent.mcp_tool_useO agent solicitou uma tool MCP.
agent.mcp_tool_resultResultado de uma tool MCP.
agent.memory_readUma tool de memória leu um documento.
agent.memory_writeUma tool de memória escreveu um documento.
agent.outputs_capturedOutputs da execução foram capturados como artifacts.
agent.skills_mountingAs skills começaram a ser montadas (ver Partida da session).
agent.skills_mountedSkills foram montadas para a session.

#Partida da session

Entre criar a session e a primeira resposta do agent existe um preparo: o ambiente de execução sobe e as skills do agent são escritas nele. Isso leva de poucos segundos a bastante mais, dependendo do tamanho das skills — e antes desses eventos não havia sinal nenhum na tela.

TipoSignificado
session.sandbox_startingO ambiente de execução está sendo provisionado.
session.sandbox_startedO ambiente ficou pronto (traz ms, quanto levou).
agent.skills_mountingAs skills do agent estão sendo escritas no ambiente.
agent.skills_mountedAs skills terminaram de ser montadas.

São dois pares — início e fim de cada fase. Use-os para mostrar progresso em vez de uma tela parada.

session.sandbox_started traz quanto o provisionamento levou, que é o que responde "está lento ou é assim mesmo?" — restaurar um snapshot leva segundos, um build frio leva bem mais:

json
{ "type": "session.sandbox_started", "ms": 4305 }

agent.skills_mounting carrega o tamanho do trabalho:

json
{
  "type": "agent.skills_mounting",
  "skills": [
    { "name": "docx", "files": 61 },
    { "name": "pdf", "files": 12 }
  ],
  "files": 73
}

Prefira files a contar as skills ao montar a mensagem: é o número de arquivos que explica a espera — três skills leves montam em segundos, enquanto as de documento sozinhas passam de 170 arquivos.

ts
for await (const event of session.stream()) {
  if (event.type === 'session.sandbox_starting') setStatus('Preparando o ambiente…');
  if (event.type === 'session.sandbox_started') setStatus(`Ambiente pronto (${event.ms}ms)`);
  if (event.type === 'agent.skills_mounting') {
    setStatus(`Montando ${event.skills.length} skills (${event.files} arquivos)…`);
  }
  if (event.type === 'agent.skills_mounted') setStatus('Pronto');
}

Garantias de emissão: o par do sandbox (sandbox_starting/sandbox_started) é emitido uma vez por session. Já agent.skills_mounting é emitido por tentativa — se a montagem falhar e for repetida no turno seguinte, você recebe outro; é o sinal de que o sistema está tentando de novo.

Uma sessão que não usa skills recebe só o par do sandbox. E se o provisionamento falhar, o sandbox_started não vem: trate sandbox_starting como um estado que pode não fechar e não bloqueie sua UI esperando por ele.

Todos são informativos: não entram no contexto do modelo e nunca chegam por ingestão.

#Eventos de status

TipoSignificado
session.requires_actionA session pausou aguardando resultado de custom tool (ver abaixo).
session.status_idleA session está pronta ou aguardando ação externa.
session.status_runningA session está processando trabalho.
session.status_rescheduledA session foi reagendada para continuar.
session.status_terminatedA session terminou.
session.errorA execução registrou falha terminal ou recuperável conforme payload.

#Eventos de observabilidade

TipoSignificado
span.model_request_startInício de uma chamada ao modelo.
span.model_request_endFim de uma chamada ao modelo, incluindo usage quando disponível.

Esses eventos ajudam a depurar latência e consumo, mas normalmente não dirigem experiência de usuário.

#Eventos entregáveis por webhook

Webhooks aceitam um subconjunto estável de alto valor operacional:

Tipo
agent.message
session.requires_action
session.status_idle
session.status_running
session.status_rescheduled
session.status_terminated

#session.requires_action

Emitido quando a session PAUSA aguardando o resultado de uma custom tool — o evento que permite responder sem manter um processo com stream aberto. O session.status_idle diz que a session parou; este diz o que está faltando.

json
{
  "sessionId": "sess_...",
  "agentId": "agent_...",
  "agentVersion": 3,
  "reason": "custom_tool",
  "pendingToolCalls": [{ "toolUseId": "toolu_...", "name": "cotar_seguro_vida" }]
}
  • reason é uma união extensível; hoje só custom_tool. Trate motivo desconhecido ignorando o evento.
  • O input da chamada não viaja no payload (é dado do seu cliente final): leia o agent.custom_tool_use correspondente no endpoint de events da session.
  • A entrega é at-least-once. Responder o mesmo toolUseId duas vezes é seguro: use a idempotencyKey determinística ctr-<toolUseId> (o default de sessions.respondTool no SDK) e o servidor grava um resultado só.
  • Não é emitido para sessions sem quem responda — caso de experimento (avaliação) e subagente de multi-agente.

#Uso no SDK

ts
import { isAgentMessage, isAgentCustomToolUse } from '@noorden/sdk';

for await (const event of session.stream({ afterSeq: checkpoint })) {
  checkpoint = event.seq;

  if (isAgentMessage(event)) {
    await appendText(event.text);
  }

  if (isAgentCustomToolUse(event)) {
    await queueTool(event.toolUseId, event.name, event.input);
  }
}