Tidebase Tidebase GitHub Start self-hosting
Docs

Fork, time travel, and snapshot AI agent runs

To rewind an agent run to an earlier point — or branch a new run from it — Tidebase models every state update as a version in a stream. A snapshot is just a labeled version, so time travel, forking, and restore all fall out of one small model:

current state = latest version in a stream
snapshot      = labeled state version
time travel   = read an older version
fork          = create new app/run context from an older version
restore       = append a new version based on an older version

Tidebase is an open-source checkpoint layer for AI agents: wrap your steps, and failed runs resume from the last safe point — in your own Postgres, without moving execution into a new runtime.

Writing versions

run.state.set() and run.state.patch() update the live run state and append to the version history:

await run.state.patch({ status: 'writing', progress: 0.7 })

Label the current state when it becomes a meaningful review or restore point:

await run.state.save('before-approval', {
  reason: 'the user is about to approve sending'
})

Snapshots of app-level targets

Snapshots are a convenience API over labeled versions for external targets — reports, artifacts, workspaces, documents, app state:

await run.snapshots.create('draft-v1', {
  target: { type: 'report', id: reportId },
  state: draft,
  reason: 'first complete draft'
})

Reading history

GET /runs/:runId/state/versions             — all versions, all streams
GET /runs/:runId/state/versions?labeled=true — labeled versions (snapshots) only
GET /runs/:runId/state/versions?stream=NAME  — one stream

What fork/restore means is yours to define

Tidebase stores and exposes the versions; your app decides what restoring a report or forking a workspace means for its own state targets. A forked run is a new run whose initial context comes from an older version — completed steps in the parent replay from checkpoints, so a fork doesn’t re-pay for work already done.

See also: Fan out to subagents · Checkpointing in Postgres