O motor emite progresso via options.onEvent (HTTP e outros transports) e via namespace Socket.IO /sequential-thinking. Os nomes dos eventos e as chaves de capítulo vêm do código-fonte (EVENTS e CHAPTER_KEYS em contracts/types.js no backend).
Envelope de cada evento
| Campo | Tipo | Descrição |
|---|
type | string | Nome do evento (ex.: step_completed) |
intentId | string | ID da execução |
sessionId | string | null | ID da sessão WebSocket, se options.sessionId estiver definido |
timestamp | string | ISO 8601 |
seq | number | Sequência monotônica global por execução |
chapterId | string | null | Ex.: execution_3 |
chapterKey | string | null | Fase atual — valores em Capítulos |
payload | object | Dados específicos do evento |
O campo progress nos eventos de step costuma ser Math.round((stepNumber / totalSteps) * 100).
Evento de fronteira: final_answer_ready
Emitido ao encerrar o pipeline. Garante que existe mensagem final coerente com a persistência. Payload inclui, entre outros: intentId, sessionId, requestControlId, status, message, fallbackApplied, safetyNet, success, interrupted, dryRun, continuationDepth, totalStepsPlanned, executedSteps, stepCountsByStatus, liveTokens, costTrackerSummary.
execution_cancel_requested
Emitido quando o cancelamento é solicitado por API ou evento cancel_intent no socket (cancelIntent + transporte). Payload típico: { reason, requestedBy, mechanism: 'immediate' | 'flagged' }. O pipeline pode seguir com execution_cancelled quando o abort efetivo ocorrer.
Catálogo por fase
Lifecycle de chapters
| Evento | Payload relevante |
|---|
chapter_started | { chapterId, chapterKey } |
chapter_log | { message, level, source, stepNumber?, action?, metadata? } |
chapter_completed | { chapterId, chapterKey, status } |
Initialization
| Evento | Payload relevante |
|---|
intent_created | { intentId } |
intent_restored | { intentId, completedCount, pendingCount } |
Preparation
| Evento | Payload relevante |
|---|
media_resolution_started | — |
media_resolved | { resolvedCount, error? } |
actions_prefilter_started | — |
actions_prefiltered | { selected, total, names[] } |
constraints_prefilter_started | — |
constraints_prefiltered | { groupCount } |
web_context_enrichment_started | — |
web_context_enriched | { appended } ou { appended: false, error } |
rag_context_enrichment_started | — |
rag_context_enriched | { appended }, { appended: false, reason: 'no_host_id' } ou { appended: false, error } |
Planning
| Evento | Payload relevante |
|---|
plan_generated | { stepCount, planSummary } (continuações podem incluir continuation: true) |
plan_review_started | — |
plan_reviewed | { corrected } ou { corrected: false, error } |
plan_loaded | { stepCount } |
plan_ready | { intentId, steps[], totalSteps, instructions } |
Feasibility
| Evento | Payload relevante |
|---|
feasibility_checked | { intentId, feasible, issues[], warnings[], clarificationSuggestions[] } |
feasibility_rejected | { attempt, maxAttempts, issues[], clarificationSuggestions[], correctiveInstruction } |
replanning_triggered | { attempt, reason } |
| Evento | Payload relevante |
|---|
input_guard_clarification | { intentId, reason, clarificationMessage, feasibilityIssues? } |
Execution
| Evento | Payload relevante |
|---|
execution_started | { totalSteps } |
step_started | { stepNumber, totalSteps, action, progress } |
step_completed | { stepNumber, totalSteps, action, result, progress } |
step_failed | { stepNumber, action, error, willRetry, retryCount } |
step_skipped | { stepNumber, action, reason } |
parallel_group_started | { stepNumbers[], groupSize } |
parallel_group_completed | { stepNumbers[], completedCount, failedCount } |
branch_resolved | { stepNumber, chosenBranchIndex, chosenBranchLabel, branchStepCount } |
execution_completed | { intentId, success, totalSteps, executedSteps, metrics, auditLog } |
execution_failed | { error, lastStep, auditLog, aiMessage?, diagnostics?, reason? } |
execution_cancelled | { cancelledAtStep, reason } |
Interruption e continuação
| Evento | Payload relevante |
|---|
execution_interrupted | { intentId, interruptionPayload, completedSteps, continuationDepth } |
continuation_started | { intentId, continuationDepth, completedCount, userResponse } |
replanning_for_continuation | { intentId, continuationDepth, completedSteps, pendingSteps } |
Containment
| Evento | Payload relevante |
|---|
containment_started | { attempt, retriesLeft } |
containment_completed | { attempt, stepsExecuted } |
containment_failed | { attempt, reason, error? } |
Recommendation replan
| Evento | Payload relevante |
|---|
step_replan_recommended | { stepNumber, action, recommendation, progress, displayName? } |
recommendation_replan_started | { stepNumber, recommendation } |
recommendation_replan_completed | { attempt, stepsExecuted } |
recommendation_replan_failed | { attempt, reason } |
Delivery comparison
| Evento | Payload relevante |
|---|
delivery_comparison_started | { attempt } |
delivery_compared | { attempt, status, objectiveCount, missingObjectives[], recoverable, reasoning } |
delivery_replan_started | { attempt, correctiveInstruction } |
delivery_gaps_remaining | { attempt, missingObjectives[], reasoning } |
status em delivery_compared: delivered, partial, undelivered ou inconclusive.
Full retry
| Evento | Payload relevante |
|---|
full_retry_started | { attempt, maxRetries } |
full_retry_interrupt | { intentId, attempt, maxRetries, failedActions[], interruptionPayload } |
Compile
| Evento | Payload relevante |
|---|
compile_started | { hasLastStepPayload } |
captures_collected | { captureCount } |
composing_message | { model, reason } (ex.: error_recovery, no_step_payload) |
final_answer_resolved | { source: 'step_payload' | 'llm_composition' | 'deterministic_fallback' } |
compile_completed | { success } |
Database query (ação queryDatabase)
| Evento | Payload relevante |
|---|
db_query_phase_started | { phase, description?, attempt?, maxAttempts? } |
db_query_phase_completed | { phase, durationMs, summary? } |
db_query_attempt_started | { attempt, maxAttempts } |
db_query_attempt_succeeded | { attempt, totalAttempts, rowCount, durationMs } |
db_query_attempt_failed | { attempt, maxAttempts?, failedAt?, reason, sql?, willRetry } |
Heartbeat, narração, métricas e contexto
| Evento | Payload relevante |
|---|
step_heartbeat | { stepNumber, action, displayName, phase, elapsedMs, timeoutMs, percentElapsed } |
status_narration | { message, sourceEvent, progress } |
token_usage_updated | { source, delta: { prompt, completion, cost, calls }, cumulative } |
cost_reconciled | { requestControlId, dbTotals, inMemoryTotals, dbRecordCount } |
performance_report | { timings } — array ordenado por duração |
context_memory_updated | { pushSeq, triggerStep, triggerAction, updatedLayer, delta, layers, budgetTokens, entryPreview? } |
Capítulos (chapterKey)
Valores usados para agrupar a timeline: initialization, preparation, planning, feasibility, continuation_planning, execution, containment, recommendation_replan, delivery_comparison, full_retry, audit, compile.
Ordene por seq; abra grupo em chapter_started e feche em chapter_completed.
WebSocket: /sequential-thinking
Autenticação na conexão:
const socket = io('/sequential-thinking', {
auth: {
token: 'BEARER_TOKEN',
sessionId: 'uuid-opcional-reconexao',
},
});
Ao conectar, o servidor cria ou retoma sessão, faz join na room da sessão e pode emitir session_started ou session_resumed e session_intents.
Cliente → servidor (sessão)
| Evento | Descrição |
|---|
start_request | Inicia execução (instructions, hostId?, conversationId?, intentId?, continuationInput?, etc.) |
cancel_intent | { intentId, reason? } — cancela execução |
watch_intent / unwatch_intent | Acompanhar ou sair de uma intent |
list_session_intents | Lista intents da sessão |
list_user_sessions | Sessões do usuário (cross-device) |
replay_events | { intentId, sinceSeq? } |
get_context_memory | { intentId, detailed? } |
get_session_db_content | Snapshot de conteúdo DB da sessão |
Servidor → cliente (sessão)
| Evento | Descrição |
|---|
session_started / session_resumed | Sessão criada ou retomada |
session_intents | Lista de intents |
session_intent_started | Nova execução na sessão |
session_error | Erro de sessão |
user_sessions | Resposta a list_user_sessions |
replay_events_response | Catch-up de eventos |
context_memory_response | Snapshot de context memory |
intent_cancel_acknowledged | Resposta a cancel_intent |
session_db_content_response | Resposta a get_session_db_content |
Compatibilidade
Entrada: join_sequential_thinking_intent, leave_sequential_thinking_intent, join_sequential_thinking_host, leave_sequential_thinking_host.
Saída: sequential_thinking_event (envelope completo), sequential_thinking_joined, sequential_thinking_joined_host, sequential_thinking_error.
Rooms
- Sessão:
st_session_{sessionId}
- Intent:
sequential_thinking_intent_{intentId}
- Host:
sequential_thinking_host_{hostId}
Em condições normais os eventos de pipeline são emitidos para as três rooms quando aplicável.
Multi-pod
O Redis Adapter do Socket.IO replica emits entre pods; não é necessário Pub/Sub manual para o cliente receber eventos originados em outro pod.
Context memory na UI
O evento context_memory_updated expõe camadas main e stepResults com estimativas de tokens. Detalhes de classificação e exemplos de consumo estão na documentação interna do repositório (EVENTS.md no módulo sequentialThinking).