Streaming and Events
A run gives you two streams. By the end of this page you will have printed an answer as the model writes it, and followed the run’s telemetry events — the model calls, tool calls and results, the final answer — while it ran and after it ended.Every output on this page is what the code printed when it was run with
gpt-5.4-mini. The model’s wording, and so the number of text deltas, will
differ on your run.Stream the answer
Passon_event to run(). It is called with each piece of text the model
writes; a plain function works, and so does a coroutine.
run() still returns the whole result
when the run ends. The last line is the other stream: every event the run
recorded, in order — two agent_steps, the tool call between them (asked of
the policy first: policy_request_created, then policy_decision_allow, since
governance is on by default), the final_answer.
Or iterate over the run
agent.stream() gives the same deltas as an async iterator, then one
complete event carrying the whole result (or one error event):
complete event has every key run() returns (response, status,
run_id, trace_id, …). Leaving the loop early — or closing the iterator —
cancels the run; aclosing makes sure that happens as soon as you stop.
What a delta carries
Text is streamed for every model turn, including what the model says before it
calls a tool.
resume(run_id, on_event=...) streams a resumed run the same way.
Follow the run’s events live
Take a cursor before the run starts, then read events after it as they are recorded.event_types narrows the stream:
stream_telemetry_after keeps waiting for new events, so stop it yourself —
here at final_answer. Each event is a TelemetryEvent with event_type,
event_id, trace_id, timestamp, actor, input, output, error,
token_usage, estimated_cost_usd and metadata; runtime events carry
run_id, session_id and agent_id in their metadata.
The events
These are the ones you will use most. What an event records (for example, whether a tool’s arguments are kept in full) follows your telemetry settings.run_resumed says why in its metadata: cause is approval, budget_grant,
budget_denied, interrupted, or recovered_after_lapsed_lease, and
trigger is explicit (a call to resume) or orphan_sweep (the server’s
sweeper). A recovered run also carries
previous_owner, lease_expired_at and orphaned_seconds, how long it sat
with no process. A decided run the sweep resumed carries decision and
decided_at instead.
Look up a finished run
Use
trace_id for one exact trace; use run_id to find a run inside a
session. A run that paused and resumed has one trace per segment, and the
run_id lookup returns the latest. Traces can also be exported to OTLP,
LangSmith or Opik (Observability).
Over HTTP
OmniServe serves the same streams:POST /runruns the agent and streams its text deltas and telemetry events as Server-Sent Events, ending withcomplete.GET /telemetry/eventsreturns stored events as JSON, filtered bytrace_id,run_id,session_id,task_idorevent_type; 200 events by default.GET /telemetry/events/stream?session_id=...replays a session’s stored events and follows new ones; addrun_idfor one run.GET /telemetry/traces/{trace_id},GET /telemetry/runs/{run_id}/traceandGET /telemetry/sessions/{session_id}/tracereturn one trace, or404.GET /telemetry/traceslists traces, 100 by default.
/events/{session_id}, /events/{session_id}/list and
/events/{session_id}/trace routes remain as compact session aliases; add
?run_id=... to isolate one run.
Background run events
Background agents add run lifecycle events, read withget_run_events(run_id) or
GET /background/runs/{run_id}/events. They are recorded in telemetry, kept by
the manager, and mirrored to the task workspace’s events.jsonl when its
workspace policy allows.
Options
The full signatures are in the OmniCoreAgent reference.
When things go wrong
TypeError: object async_generator can't be used in 'await' expression
TypeError: object async_generator can't be used in 'await' expression
agent.stream(...) is iterated, not awaited: async for event in agent.stream(...).TypeError: get_trace() requires trace_id or session_id
TypeError: get_trace() requires trace_id or session_id
Pass what to look up:
get_trace(result["trace_id"]), or
get_trace(run_id=...) / get_trace(session_id=...).ValueError: Use only one of trace_id, run_id, or session_id
ValueError: Use only one of trace_id, run_id, or session_id
Trace lookups take one key at a time.
stream_telemetry_after never ends
stream_telemetry_after never ends
It follows new events until you stop it. Break on
final_answer (or
runtime_error), or await the run’s task and stop then.No text deltas arrive
No text deltas arrive
Deltas go only to the
on_event of the run you started (or stream()),
and are not stored: they cannot be replayed from telemetry afterwards.
The telemetry events are stored, and the finished answer is in
final_answer and the run’s result.Next
Observability
Read a run as a trajectory; export traces.
OmniServe
The same streams over REST and SSE.
Background agents
Scheduled and queued runs, and their lifecycle events.
Sub-agents
Child runs, linked traces, and their events.