You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(sdk): route chat.agent transcript persistence through a TranscriptStorage seam (#4893)
## Summary
Introduces the `TranscriptStorage` seam inside `chat.agent` and makes
the built-in snapshot writer its default implementation. No public
option yet; the default path behaves as before, apart from the blob now
being written as version 2.
## Design
A storage has `load` (called once when a run boots to continue a
conversation) and `save` (called after every turn, failed turn and
history-changing action). `save` receives a changeset of id-addressed
operations: `put` (upsert by message id), `remove`, `truncateAfter` and
`state`, plus the stream cursors the next boot resumes from.
The runtime keeps a shadow of the transcript it last handed to `save`
(ids in order plus a fingerprint per message) and diffs the accumulator
against it. A changed message in the common prefix is an in-place `put`;
anything past the prefix is one `truncateAfter` on the last common id
followed by `put`s in order. Applying the result reproduces the
accumulator exactly for any edit, and the common cases come out as the
natural operations: a turn is two `put`s, an undo is one
`truncateAfter`, a regenerate is a `truncateAfter` and a `put`. The
shadow only advances when `save` resolves, so a failed save is folded
into the next changeset; every operation is idempotent, so a retried
changeset converges.
Every changeset also carries the whole transcript as it stands after the
changes (entries with a `final` flag, plus the runtime's `state`). A
row-per-message store applies the changes; a store that keeps the
conversation as one document writes the transcript as-is and needs no
state of its own between saves. The default storage is the second kind:
it serialises the transcript and rewrites the blob, so a turn still
costs one PUT and no GET, and nothing is held in memory between saves.
The snapshot read and write helpers move to their own module so the
storage can import them without a cycle; the test seams keep their
import path.
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
0 commit comments