Skip to contents

gptr_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 (-1 undoes the last turn); 0 goes back to before the first turn; k > 0 keeps turns 1..k of the active path.

to

An entry id from gptr_checkpoints(s, all = TRUE); overrides turn. 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 key checkpoint).

  • 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)