Rewind a session: undo turns, restore objects and files, move the conversation
Source:R/ckpt-rewind.R
gptr_rewind.Rdgptr_rewind() is a branch-in-place on the one session object: it undoes the checkpoint
records of the turns being left (newest first), redoes the records of a target on another
branch (oldest first) and appends one gptr.rewind entry parented at the target (the session
file stays append-only and the rewind survives a reload). It hands back the undone prompt in
s$editor_text and returns s invisibly, so it pipes:
session |> gptr_rewind() |> peter("Try another way"). Use gptr_fork() for a second
session.
gptr_checkpoints() lists one row per turn of the active path (all = TRUE adds the turns of
abandoned branches): turn; id, the last entry of the turn (pass it as to to
gptr_rewind()); time, when the prompt was sent; prompt (its first 60 characters);
objects and files, "changed/restorable" counts; held_mb and disk_mb, megabytes of
object pre-images held in memory and on disk; and branch ("active" or "abandoned").
Usage
gptr_rewind(
s,
turn = -1L,
to = NULL,
restore = c("all", "conversation", "workspace"),
force = FALSE,
preview = FALSE
)
gptr_checkpoints(s, all = FALSE)Arguments
- s
A
gptr_session.- turn
Integer. Negative counts back from the last turn (
-1undoes the last turn);0goes back to before the first turn;k > 0keeps turns1..kof the active path.- to
An entry id from
gptr_checkpoints(s, all = TRUE); overridesturn. Any entry works, including the end of an abandoned branch, which is how redo works.- restore
"all"(objects, files, session state and the conversation),"conversation"(only the conversation) or"workspace"(only objects, files and session state; the conversation stays where it is).- force
Also restore items that changed after the checkpoint (3-way conflicts).
- preview
Return the plan instead: a data frame with one row per item (
record,turn,action,checkpointer,item,restore,reason); nothing changes.- all
Also list the turns of abandoned branches.
Value
gptr_rewind() returns s, invisibly (the plan when preview = TRUE);
s$last_rewind holds the report and s$editor_text the undone prompt.
gptr_checkpoints() returns a gptr_checkpoints data frame (it prints at most 20 rows).
Details
Restores are 3-way: an object or file that changed after the turn (by you or another session)
is kept and reported, unless force = TRUE. Reference objects (environments, R6, external
pointers), objects over the undo budget, environment variables, loaded namespaces, the
random-number state and effects outside R (network, databases, processes) are not restored.
Items that were not restored are listed in s$last_rewind$report and raise the warning
gptr_warning_rewind_partial. Files outside the project and tempdir() are restored only
after you confirm each path. After a full restore the model is told nothing (the next
request's prefix is byte-identical to the earlier request at the target); after a partial one
the next prompt carries a short <rewind> block listing what was not restored. Model code may
rewind another session only when you approve that call.
Options
Options of checkpoints and rewind (?gptr_options collects every option):
gptr.checkpoint("on"):"files"checkpoints files only,"off"nothing (also the settings keycheckpoint).gptr.undo_capture_max(1e8): bytes; objects up to this size are captured by reference.gptr.undo_max_bytes(1e9): bytes of pre-images held in memory per session.gptr.undo_spill_max(2e9): bytes; the largest object image written to disk.gptr.undo_turns(20): object images older than this many turns are dropped.gptr.checkpoint_disk_bytes(2e9): bytes of blobs and spilled images before a notice.gptr.checkpoint_days(30): unreferenced blobs older than this many days are deleted.gptr.checkpoint_turns(100): file checkpoints older than this many turns are not restored.gptr.checkpoint_track_file_max(1e6),gptr.checkpoint_track_total(1e8): bytes per file and in all of the baseline taken at the first mutating call.gptr.checkpoint_capture_max(5e7): bytes; a larger changed file gets no stored copy.gptr.checkpoint_scan_budget(0.25): seconds; slower walks switch to one scan per turn.gptr.checkpoint_rng(TRUE): report changes of the random-number state.gptr.checkpoint_close_devices(FALSE): close graphics devices an undone turn opened.
Examples
d = tempfile("project")
dir.create(d)
op = options(gptr.project_root = d)
fake = gptr_fake_provider(list(
list(tool = "r", input = list(code = "x = 1")), "Made x.",
list(tool = "r", input = list(code = "x = x + 1")), "Added one."))
work = new.env()
session = peter("Make x", model = fake, mode = auto, envir = work)
#> gptr: thinking
#> gptr: r x = 1
#> gptr: thinking
#> gptr: done · 1 turn · 3.2k tokens · $0.0000
session |> peter("Add one to x")
#> gptr: thinking
#> gptr: r x = x + 1
#> gptr: thinking
#> gptr: done · 2 turns · 3.3k tokens · $0.0000
#> Added one.
#> idle · fake/fake-1 · 2 turns · 6.5k tokens · $0.0000 · s821e7f6633
work$x
#> [1] 2
session |> gptr_rewind()
work$x
#> [1] 1
session$editor_text
#> [1] "Add one to x"
gptr_checkpoints(session, all = TRUE)
#> # Columns 1/2
#> id branch turn time prompt objects files held_mb
#> 1 81312576 active 1 2026-10-1... Make x 1/1 0/0 0
#> 2 ba2caa55 abandoned 2 2026-10-1... Add one to x 1/1 0/0 0
#> # Columns 2/2
#> disk_mb
#> 1 0
#> 2 0
#>
#> # 2 rows
#> Rewind with gptr_rewind(s, <turn>) or gptr_rewind(s, to = "<id>").
options(op)