Time-Travel Debugging
advanced15 mintime-travel.ts
A multi-step run went somewhere unexpected. You want to replay it from a step, or fork it with a different instruction and diff the paths.
What it shows
- Checkpoint every step with
TimeTravel - Replay, fork with new input and compare
The code
time-travel.ts
import { Agent, Cogitator, InMemoryCheckpointStore, TimeTravel, tool } from '@cogitator-ai/core';
import { z } from 'zod';
const apiKey = process.env.GOOGLE_API_KEY;
if (!apiKey) throw new Error('Set GOOGLE_API_KEY');
const inventory: Record<string, number> = { wood: 100, stone: 80, iron: 30, gold: 5 };
const recipes: Record<string, Record<string, number>> = {
wooden_sword: { wood: 10 },
stone_pickaxe: { wood: 5, stone: 15 },
iron_armor: { iron: 20, wood: 5 },
gold_ring: { gold: 2 },
};
const checkInventory = tool({
name: 'check_inventory',
description: 'Check current inventory of materials',
parameters: z.object({}),
execute: async () => ({ ...inventory }),
});
const craft = tool({
name: 'craft',
description: 'Craft an item: wooden_sword, stone_pickaxe, iron_armor or gold_ring',
parameters: z.object({ item: z.string() }),
execute: async ({ item }) => {
const recipe = recipes[item];
if (!recipe) return { error: `Unknown item: ${item}` };
for (const [material, amount] of Object.entries(recipe)) {
if ((inventory[material] ?? 0) < amount) return { error: `Not enough ${material}` };
}
for (const [material, amount] of Object.entries(recipe)) inventory[material] -= amount;
return { crafted: item, remaining: { ...inventory } };
},
});
const cog = new Cogitator({ llm: { providers: { google: { apiKey } } } });
const timeTravel = new TimeTravel(cog, { checkpointStore: new InMemoryCheckpointStore() });
const crafter = new Agent({
name: 'crafter',
model: 'google/gemini-3.5-flash-lite',
instructions: 'You are a game crafting assistant. Check inventory first, then craft what is asked.',
tools: [checkInventory, craft],
temperature: 0.2,
maxIterations: 10,
});
const original = await cog.run(crafter, {
input: 'Check our inventory, then craft a stone_pickaxe and a wooden_sword.',
});
console.log('Original path:', original.toolCalls.map((call) => call.name).join(' -> '));
const checkpoints = await timeTravel.checkpointAll(original, 'craft-session');
console.log(`Saved ${checkpoints.length} checkpoints`);
const replay = await timeTravel.replay(crafter, checkpoints[0].id, { mode: 'live' });
console.log(`Replayed ${replay.stepsReplayed} steps, executed ${replay.stepsExecuted} new ones`);
const fork = await timeTravel.forkWithNewInput(
crafter,
checkpoints[0].id,
'Craft a gold_ring and an iron_armor instead. Check inventory first.',
'alt-craft-path'
);
console.log('Fork path:', fork.result.toolCalls.map((call) => call.name).join(' -> '));
const diff = await timeTravel.compareWithOriginal(fork.result);
console.log(timeTravel.formatDiff(diff));
await cog.close();Run it
install · bash
pnpm add @cogitator-ai/core zodEnvironment
GOOGLE_API_KEYrun · bash
GOOGLE_API_KEY=your-key npx tsx time-travel.tsOr run the full example from a clone of the repository (keys in .env):
repository · bash
npx tsx examples/core/08-time-travel.ts