SESSIONS · REPLAY AFTER A CRASH
Session recovery: replay recorded transitions
Record a short ticket-booking conversation as session events, crash the process, and rebuild state by replaying only what was persisted.
Your experiment
A user adds two tickets, then one more; a network retry appends the second cart change twice; the agent then sets a VIP discount by writing to the session object it fetched. The process restarts and state is rebuilt from the event log. Compare the recovered cart and discount with what the user saw.
Play replays the computed run over sixty inspection seconds; Next event steps, Restart rewinds, and Inspection time scrubs. Any input change recomputes the run and rewinds it without autoplay.
Event trace
Computed data
Final metrics
ADK-style fixture: an event’s state_delta is stored with the event and replayed on recovery, temp: keys are not persisted, and a value written to a fetched session object without an event is never recorded. ADK state_delta holds absolute values; the increment format is an application choice shown for contrast. No session service, database or runtime is called.
State is rebuilt from events
A session keeps an append-only list of events, and each event may carry a state_delta. A durable session service stores events with their deltas; after a restart, the session’s state is whatever replaying those deltas produces. In the fixture a user adds 2 tickets (E1, E2), the agent quotes Q-77 with a temp:quote key (E3), the user adds 1 more (E4, E5), and the agent applies a VIP discount (E6). Before the restart the live session shows cart 3 and discount VIP. The question is whether replay reproduces it.
The opening run: cart 4 and no discount
Cart changes are recorded as increments, cart += 2 and cart += 1, and a network retry appends E5 a second time. The agent sets the discount by writing session.state["discount"] on the session object it fetched, so no event records it. After the restart, replaying 6 persisted events gives cart 2 + 1 + 1 = 4 and no discount: two divergences from what the user saw. The temp:quote key is also gone, which is correct: temp: keys are turn-local and never persisted.
Failure boundary: absolute deltas and recorded changes
Set How cart changes are recorded to As absolute values: E5 says cart = 3, so applying it twice still gives 3, and the duplicate becomes harmless for state; ADK’s state_delta has this shape. Set How the agent sets the VIP discount to Through an event state_delta: E6 is persisted and replay restores VIP. With both changes the recovered state matches (cart 3, discount VIP), but the history still contains E5 twice, which a model reading the conversation would see. Turn on Store drops an event id it already has and the second E5 is rejected at append time, which fixes the history and also the increment arithmetic.
Other inputs
Turn off A network retry appends E5 twice and increments replay correctly to 3; the direct discount write is still lost. Set Process restart to After E5, before the discount: the expected state is just cart 3, so only the duplicate matters. With No restart the in-memory session keeps cart 3 and VIP whatever the recording method, which is why these bugs survive testing: they appear only when state is rebuilt from storage. Store drops an event id only matters when a duplicate is sent.
Reading the run and its limits
Play replays each append, the direct write, the restart, the replay and the comparison over sixty inspection seconds; Next event, Restart, Speed and Inspection time control the replay, and any input change recomputes it. The table lists exactly what was persisted. This is a fixture: there is no session service, database, optimistic concurrency check or runtime; one deduplication rule stands in for idempotent appends, and the increment format is an application choice shown for contrast, not an ADK feature.