Serialization Proposal
Summary
Problem Statement
Currently, there’s no standardized way to serialize and restore AG-UI event streams, making it difficult to reload chat history, attach to running agents, or implement branching/time travel features.Motivation
AG-UI adds stream serialization to reload chat history and attach to active agents, enabling restoration and interaction with live state. A standardizedcompactEvents(events: BaseEvent[]): BaseEvent[]
reduces already-streamed
events and normalizes inputs. Additionally, RunStartedEvent
gains
parentRunId
for branching/time travel and an input
field carrying the exact
AgentInput
sent to the agent (which may omit messages already present in
history).
Status
- Status: Draft
- Author(s): Markus Ecker (mail@mme.xyz)
Detailed Specification
Overview
This proposal introduces three key capabilities:- Stream serialization - Serialize/deserialize event streams for persistence and restoration
- Event compaction - Reduce event volume while preserving semantic meaning
- Run lineage tracking - Enable branching and time travel with parent run references
Git-like Branching Model
TheparentRunId
field enables a git-like branching structure where the entire
conversation history can be stored as a continuous serialized stream, with each
run forming nodes in a directed acyclic graph:
Key Benefits of This Append-Only Architecture:
- Immutable History: Events are never modified or deleted, only appended
- Serializable Stream: The entire DAG can be stored as a single continuous stream of events
- Multiple Branches: Different conversation paths coexist in the same serialized log
- Time Travel: Navigate to any point in any branch without data loss
- Efficient Storage: Compaction reduces redundancy while preserving the full graph structure
Proposed Changes
Stream Serialization
Support serializing/deserializing the event stream so chat history can be reloaded and sessions can attach to running agents/live state.Event Compaction
IntroducecompactEvents(events: BaseEvent[]): BaseEvent[]
to:
- Reduce the number of already-streamed events
- Normalize
RunStartedEvent.input
so it contains only the messages that were not already sent/recorded earlier in the thread
Run Lineage and Input Capture
ExtendRunStartedEvent
with:
parentRunId?: string
to enable branching/time travel - similar to git commits, this creates an append-only log where each run points to its parent, forming a directed acyclic graph of conversation branchesinput?: AgentInput
containing the agent input exactly as sentinput.messages
may omit messages already present in historycompactEvents
normalizes this field to a minimal form
Updated Types
Event Compaction Rules
ThecompactEvents
function applies these transformations:
Message Events
- Consecutive
TEXT_MESSAGE_CONTENT
events with samemessageId
→ single event with concatenated content - Complete message sequences (START + CONTENT + END) → single snapshot event
- Tool call sequences → compacted tool invocation records
State Events
- Multiple
STATE_DELTA
events → singleSTATE_SNAPSHOT
with final state - Redundant state updates → removed if superseded by later snapshots
Run Input Normalization
- Messages in
RunStartedEvent.input
that exist in prior events → removed - Only new/incremental messages retained in normalized form
Implementation Examples
Basic Serialization
Event Compaction Example
Before compaction:Branching with Parent Run ID
TheparentRunId
field creates a git-like branching model where the event
stream becomes an immutable, append-only log. Each run can branch from any
previous run, creating alternative conversation paths without modifying the
original history.
- No existing events are ever modified or deleted
- Multiple branches can coexist in the same event stream
- You can always trace back the full lineage of any conversation branch
- Time travel and undo operations are possible without data loss
Normalized Input Example
Use Cases
Session Restoration
Reload a previous chat session with full history and state.Live Agent Attachment
Connect to an already-running agent and receive ongoing events.Branching Conversations
Create alternative conversation branches from any point in history.Time Travel Debugging
Navigate to any point in conversation history for debugging.Efficient Storage
Compact events before long-term storage to reduce size.Implementation Considerations
Client SDK Changes
TypeScript SDK:compactEvents
function implementation- Serialization/deserialization utilities
- Branch management helpers
- Storage adapter interfaces
- Event compaction algorithm
- Serialization utilities
- Parent run tracking
- Storage abstractions
Storage Considerations
- Support for various storage backends (memory, database, file)
- Incremental storage for append-only events
- Compression support for serialized streams
- Indexing strategies for quick access
Testing Strategy
- Unit tests for compaction algorithm
- Round-trip serialization tests
- Branch/merge scenario tests
- Performance benchmarks for large event streams
- Storage adapter integration tests