Skip to Content
cuelo.

05Observe

Events and hooks

Every call is a stream of events — hook into them, query them, replay them.

Every step of a call emits an event. Events are:

  1. stored with the session in the database,
  2. streamed to Realtime and PCM clients and the dashboard,
  3. passed to your on_event hook.

An event has session_id, kind, t (seconds into the call), turn_id and data (a dict).

Hooking in

src/events.py
from cuelo.runtime.events import Event


async def on_event(event: Event) -> None:
    if event.kind == "turn.ended" and event.data["role"] == "user":
        print(f"[{event.session_id}] user: {event.data['text']}")
    if event.kind == "session.ended":
        await notify_crm(event.session_id)

The hook may be sync or async. Exceptions are logged and never break the call. Outside a project, pass Harness(build, on_event=...).

Kinds

Kinddata
session.startedagent, config
session.updatedwhat the client changed, e.g. voice
session.endedreason
turn.startedrole
turn.endedrole, text, interrupted
stt.partialtext
stt.finaltext, finalized, start, end, language
controller.signalcontroller, signal, audio_t, text
policy.decisionaction, audio_t, text
llm.startedmodel
llm.first_token—
llm.deltatext. Live only, not stored.
llm.completedtext, stop_reason, input_tokens, output_tokens
tool.calledid, name, arguments
tool.resultid, content, is_error
tts.startedtext
tts.first_audio—
tts.endedinterrupted
agent.interrupted— agent audio stopped. Clients must drop buffered audio.
backchannel.playedtext
audio.savedside, uri, sample_rate, start, duration
summary.createdtext, model
errorcomponent, message

The list lives in cuelo.runtime.events.Kind.

Events are also stored with each call. See Storage for the database, recordings and the JSON API over them.

On this page