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:
| Tipo | Payload | Uso |
|---|---|---|
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
| Tipo | Quando ocorre |
|---|---|
agent.message | O agent produziu resposta textual. |
agent.thinking | O provider expôs conteúdo de raciocínio apresentável. |
agent.tool_use | O agent solicitou uma built-in tool. |
agent.tool_result | Resultado de uma built-in tool. |
agent.custom_tool_use | O agent solicitou uma custom tool executada pelo seu backend. |
agent.mcp_tools_listed | Tools MCP foram resolvidas para a session. |
agent.mcp_tool_use | O agent solicitou uma tool MCP. |
agent.mcp_tool_result | Resultado de uma tool MCP. |
agent.memory_read | Uma tool de memória leu um documento. |
agent.memory_write | Uma tool de memória escreveu um documento. |
agent.outputs_captured | Outputs da execução foram capturados como artifacts. |
agent.skills_mounting | As skills começaram a ser montadas (ver Partida da session). |
agent.skills_mounted | Skills 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.
| Tipo | Significado |
|---|---|
session.sandbox_starting | O ambiente de execução está sendo provisionado. |
session.sandbox_started | O ambiente ficou pronto (traz ms, quanto levou). |
agent.skills_mounting | As skills do agent estão sendo escritas no ambiente. |
agent.skills_mounted | As 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:
{ "type": "session.sandbox_started", "ms": 4305 }agent.skills_mounting carrega o tamanho do trabalho:
{
"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.
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
| Tipo | Significado |
|---|---|
session.requires_action | A session pausou aguardando resultado de custom tool (ver abaixo). |
session.status_idle | A session está pronta ou aguardando ação externa. |
session.status_running | A session está processando trabalho. |
session.status_rescheduled | A session foi reagendada para continuar. |
session.status_terminated | A session terminou. |
session.error | A execução registrou falha terminal ou recuperável conforme payload. |
#Eventos de observabilidade
| Tipo | Significado |
|---|---|
span.model_request_start | Início de uma chamada ao modelo. |
span.model_request_end | Fim 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.
{
"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
inputda chamada não viaja no payload (é dado do seu cliente final): leia oagent.custom_tool_usecorrespondente no endpoint de events da session. - A entrega é at-least-once. Responder o mesmo
toolUseIdduas vezes é seguro: use aidempotencyKeydeterminísticactr-<toolUseId>(o default desessions.respondToolno 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
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);
}
}