Concepts · durable
Transcript Tree
One append-only tree and a leaf pointer, from which edit, retry, rewind, fork, and compaction all follow
- Implementing edit, retry, or rewind on a conversation
- Exploring an alternative direction without losing the original
- Shrinking a conversation that outgrew the context window
This page gives you the tree model behind edit, retry, rewind, fork, and compaction.
The transcript is an append-only tree. Every entry carries its parent’s ID. That pointer is the entire structure. The store stays a flat log. The agent derives the tree from that log by walking parents.
A single piece of mutable state sits on top: the leaf, the entry that the next turn will attach to. Nearly every conversation operation changes the leaf. That is why the API has fewer verbs than the feature list suggests.
Why a tree and not a list
The obvious model for a conversation is a list that you append to. It breaks at the first edit. When a user rewrites their last message, they want the answer that follows from the new text. A list can produce that answer only by removing the old branch. That loses the branch the user wants when the retry turns out worse than the original.
A tree keeps both. Rewriting is not a removal. It is a second child of the same parent. The abandoned branch stays in the store, addressable and complete. Nothing in the log is ever mutated or removed.
The active path is the walk from the leaf back to the root, reversed. Everything the model and reader see is a projection of that path. Moving the leaf changes the conversation without touching a single stored entry.
Branch is the only rewind primitive
Branch moves the leaf to an earlier entry. That is all it does. It is enough for a family of features that usually get separate implementations:
- Edit — branch to the entry before the message being replaced, then run with the new text.
- Retry — branch to the same point and run again.
- Rewind — branch and stop.
A checkpoint is an entry ID you remembered. Capture LeafID() before a risky turn. Pass it back to Branch to undo everything since.
checkpoint := da.LeafID()// ... a turn that may go badly ..._ = da.Branch(ctx, checkpoint)The leaf lives in memory. When a session reopens, it resumes at the last appended entry. It does not resume wherever you had branched to. A rewind is a property of a working instance, not a stored fact about the conversation.
Fork copies the path into a new session
Branching explores an alternative inside one session. Fork lifts the active path into a separate session. It re-chains the path with fresh entry IDs and records the original as its parent.
Use it when the alternative must have its own identity. Examples include a what-if that the user will return to, or a sub-conversation with its own lifetime. Use a sibling branch when the alternative shares the original session ID.
The durable agent copies entries because it owns the transcript working set. The child record carries only its ID, its parent’s ID, and a creation time. If the child must inherit application metadata, the application copies that metadata in its own storage.
Compaction summarizes without deleting
When a conversation outgrows the context window, Compact appends a CompactionEntry. That entry holds a model-written summary of earlier turns and the ID of the first entry kept verbatim.
Nothing is removed, and that property matters. The summary changes only how the path is projected. The model view emits the summary as a user message. It elides everything before the kept point and keeps the rest as written. The full history is still in the tree, still on the path, and still rewindable. Branching to a pre-compaction entry gives you the uncompacted conversation back.
KeepTurns controls how many recent turns stay verbatim. CompactPrompt overrides the instruction given to the summarizer. The same model and options build a throwaway agent that writes the summary, so compaction needs no separate model. Custom entries pass through untouched.
Related
- Entries — what the nodes are, and which of them the model and reader each see
- Sessions — identity, lineage, and the store the tree is written to
- Durable Events — notifications when the leaf or tree changes
- Agent State — reading state during and after a run