• English
  • Events

    Every run of the kernel yields a single typed stream: AgentEvent, a discriminated union covering everything the loop does — model calls, tool executions, approvals, compaction, errors, and the final result. This is how you build UIs, logs, and telemetry on top of lite-agent: consume the stream and render it. Events are observe only — handling an event never changes agent behavior.

    Usage

    Consume the stream with agent.run(...) and discriminate on ev.type:

    import { createAgent, nativeCodec, fakeProvider, textBlock } from "@lite-agent/core";
    
    const agent = createAgent({
      model: fakeProvider([
        { text: "hi", message: { role: "assistant", content: [textBlock("hi")] } },
      ]),
      codec: nativeCodec(),
    });
    
    for await (const ev of agent.run("hello")) {
      if (ev.type === "text_delta") process.stdout.write(ev.text);
    }

    Events forwarded from a subagent carry an agentId; the main agent's events don't.

    The AgentEvent union

    EventPayloadEmitted when
    turn_startturnA turn begins.
    model_call_startturn, modelA model call starts.
    model_call_endturn, model, durationMs, usage?, error?A model call finishes (or fails).
    text_deltatextA streamed text chunk arrives.
    messagemessageThe full assistant message for a turn is complete.
    tool_usecallThe model requested a tool call.
    tool_call_startcall, turnA tool call starts executing.
    tool_call_endid, name, turn, durationMs, isErrorA tool call finishes.
    tool_recoveredid, name, turnAn interrupted call is closed on resume (safe crash recovery).
    tool_resultresultA tool result is fed back into the conversation.
    permission_decisioncall, decision, ruleId?, reason?, simulated?, byThe permission layer decides allow / deny / ask (by: policy / user / auto).
    approval_requestcall, reason?An ask verdict suspends the call for approval.
    approval_resolvedid, decision, byThe approval handler answered.
    input_requestcall, questionThe model asks the user a question (ask_user).
    input_resolvedid, answerThe input handler answered.
    steermessagesInput was injected mid-run via a SteerController.
    compactionkind, before, after, phase?Context compaction starts / finishes (micro / auto / manual).
    context_statussessionId, level, reason, beforeTokens, afterTokens, generation, plannerUsed, plannerFallback, plannerLatencyMs, archiveRefs, retryThe ContextEngine reports automatic context management.
    background_completedcompletionA background task finished.
    diagnosticlevel, code, messageNon-fatal diagnostics (info / warning / error).
    turn_endturn, stopReasonA turn ends (stop / tool_use / max_tokens).
    errorerror, fatalAn AgentError occurs; fatal ends the run.
    donereason, resultThe run finishes (stop / aborted / max_turns) with the final RunResult.
    Info

    Non-fatal failures (a retried model call, a codec repair attempt) surface as { type: "error", fatal: false } events before any throw, so observers see the full story.

    Emitting your own events

    Middleware and tools can emit through ctx.emit(ev); the kernel buffers those events in a queue and drains it at loop boundaries. Emitting never pauses the loop, and a slow consumer never blocks the kernel — see drain semantics.

    See also

    • The kernel — the loop that produces this stream, and drain semantics.
    • Middlewarectx.emit and the layers that observe the loop.
    • Context compaction — the compaction and context_status events.
    • Persistence — the durable SessionEvent log behind session replay.