Live Vs Durable Events
The live event stream and durable branch history are related, but they are not the same thing.
Use live events to render what is happening now. Use branch history when you need replay, audit, or persisted conversation state.
Live Events
Live events are emitted while a run is happening:
using var all = agent.SubscribeAny(evt =>
{
ui.Render(evt);
});
await agent.RunAsync("Draft a short answer.");Live events can include:
- text and reasoning deltas
- tool lifecycle events
- permission requests
- custom progress events
- workflow and subagent events
- retry and diagnostic events
- trace/span metadata
They are the best source for responsive UIs and hosted streaming clients.
Durable Branch History
Durable branch history stores the events and projections needed to rebuild branch state.
Do not assume an event is durable just because it appears in the live stream. Events persist only when the branch conversion path maps them or the event type opts into branch persistence and the branch store path supports it.
Common Rule Of Thumb
| Event family | Live stream | Durable branch history |
|---|---|---|
| Text output | yes | generally yes |
| Reasoning output | yes | generally yes |
| Tool calls | yes | generally yes |
| Permission requests/responses | yes | generally no |
| Custom progress events | yes | no by default |
| Retry and diagnostics | yes | generally no |
| Compaction observability | yes | no by itself |
| Branch-history compaction | may be observed indirectly | yes when hard retention is applied |
| Workflow events | yes | validate per workflow path |
| Audio runtime events | yes | policy-dependent |
| Struct events | process-local only | no |
When in doubt, test the exact session and branch path your app uses.
Compaction Events
CompactionEvent is live middleware observability. It tells clients that compaction was skipped or performed and can include counts, reason text, and summary details.
BranchHistoryCompactedEvent is different. It is a durable branch-history event written under hard retention. Branch projection uses it to remove durable compacted message ids and insert replacement messages.
Render CompactionEvent in diagnostics. Render projected branch messages as canonical durable history.
Struct Events
AgentStructEvent values are not AgentEvent values. They use a process-local StructEventHub for hot-path samples such as audio playout frames, queue depth, provider ticks, or other realtime telemetry.
Use struct events when the value is useful to local observers but should not be streamed over hosted APIs, replayed as branch history, or treated as semantic workflow state.
Selected struct events can be serialized with AgentStructEventSerializer for explicit export or diagnostics. That is separate from hosted AgentEvent streaming. If the same fact needs to appear in a UI stream or durable branch, emit an AgentEvent intentionally or project the struct sample into one.
Custom Events
Custom events are live by default:
public sealed record RetrievalProgressEvent(
string Query,
int DocumentsScanned,
int DocumentsMatched) : AgentEvent;That is enough for subscriptions, hosted streams, dashboards, and traces.
If a custom event must be durable, design the storage and replay path deliberately. Overriding ShouldPersistToBranch() is only event type policy; your branch projection still needs to store, load, and render the event in a way your product understands.
JSON Shape Caveat
Live event envelopes include version and type fields:
{
"version": "1.0",
"type": "TEXT_DELTA",
"text": "hello",
"messageId": "message-id"
}Durable branch event documents are storage records. They may omit live routing and correlation fields. Use live envelopes for SSE/WebSocket examples, and use branch event documents only when documenting storage behavior.