Recipes
Time-travel debug
Step through a recorded agent session, rewrite a tool result, and replay from that point forward.
You recorded a session with deterministic replay. The bug happens after a specific tool call returns bad data. You want to rewrite the tool result and re-run from there — without re-recording.
createTimeTravelSession from @agentskit/eval/replay wraps a
cassette in a cursor: step through it, override any chunk, fork at
an index to get a fresh cassette, and hand that cassette to a replay
adapter.
Install
npm install -D @agentskit/evalStep through a session
import { loadCassette, createTimeTravelSession } from '@agentskit/eval/replay'
const cassette = await loadCassette('./fixtures/bug-427.cassette.json')
const session = createTimeTravelSession(cassette)
console.log('total chunks:', session.length)
let chunk = session.step()
while (chunk) {
console.log(session.cursor, chunk)
chunk = session.step()
}Rewrite a tool result, fork, replay
The workflow:
- Find the chunk index where the broken tool result was emitted.
override(index, {...})with a corrected chunk.fork(index + 1)— everything up to and including the fix, discarding the broken tail.- Feed the forked cassette into
createReplayAdapterto re-run.
import { createReplayAdapter, loadCassette, createTimeTravelSession } from '@agentskit/eval/replay'
import { createRuntime } from '@agentskit/runtime'
const session = createTimeTravelSession(await loadCassette('./fixtures/bug-427.cassette.json'))
session.override(12, {
type: 'tool_call',
toolCall: { id: 'call_3', name: 'lookup_user', args: '{"id":42}', result: '{"plan":"pro"}' },
})
const fork = session.fork(13)
const runtime = createRuntime({ adapter: createReplayAdapter(fork, { mode: 'sequential' }) })
const rerun = await runtime.run('/* same initial prompt */')API
| Method | Description |
|---|---|
length | Total flattened chunk count |
cursor | Current read position |
peek(i) | Read chunk at absolute index without moving cursor |
step() | Return chunk at cursor, advance cursor |
seek(i) | Jump cursor to absolute index |
override(i, chunk) | Replace chunk at index — returns prior value |
fork(i) | Return a new cassette containing chunks [0, i) |
snapshot() | Full copy of current (possibly mutated) cassette |