Advance Time
Simulate time passing for an agent — fire schedules, generate diaries, decay mood, and replay what would have happened without waiting real time.
Advance Time compresses real-world time into simulated time for an agent. Useful for character AI that needs in-game time to pass faster than real time, game loops that simulate days of agent state in seconds, or anywhere you want to see what the agent would be like after a period of elapsed time — without actually waiting for it.
What you can build with it
- Character AI / visual novel time skips — the protagonist sleeps for 8 hours; advance agent time by 8 hours and get the diary entry and mood changes that would have happened overnight
- Tamagotchi and life-sim game loops — in-game days pass faster than real time; call
advanceTimeeach tick to keep agent state (mood, memory, habits) in sync with the game clock - Tutorial onboarding — show a new user what their companion will "remember" after a week by fast-forwarding through a sample history before they send their first real message
- Deterministic replay — reproduce the exact agent state after X hours at any time, for debugging, snapshotting, or building a save/load system
- Eval and benchmarking — compress long-running scenarios into fast test runs (see Also useful for evaluation below)
Quickstart
Advance an agent's clock by 24 hours and inspect the diary entry generated for that simulated day.
import { Sonzai } from "@sonzai-labs/agents";
const client = new Sonzai({ apiKey: process.env.SONZAI_API_KEY! });
const result = await client.workbench.advanceTime({
agentId: "agent_abc",
userId: "user_123",
simulatedHours: 24,
});
// result.diary_entries contains any diary entries generated during the window
console.log(result.days_processed); // 1
console.log(result.diary_entries); // [{ content: "...", created_at: "..." }]Core concepts
What fires when time advances
A single advanceTime call runs the full production background worker fleet for each complete 24-hour day in the window, then resolves any proactive wakeups due within it. Concretely:
- Diary generation — one diary entry per simulated day, written from the agent's perspective
- Mood decay — emotional state drifts toward the agent's baseline at the rate it would in real time
- Memory consolidation — facts, events, and commitments are consolidated and deduplicated as they normally would be overnight
- Constellation extraction — personality signals extracted from conversation history are processed on schedule
- Scheduled wakeups — any wakeup whose
scheduled_atfalls inside the advance window fires with its intent
Pass simulatedHours: 25 (one day plus a sliver) when you need the weekly consolidation gate to tick over.
Deterministic state transitions
Given the same agent state at the start, the same advanceTime call produces the same output. There is no randomness seeded from wall-clock time. This makes Advance Time suitable for save/load, replay, and regression testing.
Async mode for long windows
For advances that would exceed a proxy read timeout (Cloudflare's limit is ~100 s, which corresponds to roughly 4–5 simulated days depending on agent complexity), pass runAsync: true. The API returns immediately with a job descriptor; poll getAdvanceTimeJob until the status is terminal.
// Kick off a long advance asynchronously
const job = await client.workbench.advanceTime({
agentId: "agent_abc",
userId: "user_123",
simulatedHours: 168, // one week
runAsync: true,
}) as { job_id: string; status: string };
console.log(job.job_id, job.status); // "job_01HX...", "running"
// Poll until done (30-minute TTL in Redis)
let state = await client.workbench.getAdvanceTimeJob(job.job_id);
while (state.status === "running") {
await new Promise(r => setTimeout(r, 2000));
state = await client.workbench.getAdvanceTimeJob(job.job_id);
}
console.log(state.status); // "succeeded"
console.log(state.result); // full AdvanceTimeResponseTime granularity
The smallest meaningful unit is one full 24-hour simulated day. Background jobs (diary, consolidation, constellation) run once per day. Sub-day advances (e.g. simulatedHours: 8) still process wakeups and mood decay but will not generate a diary entry unless a full day boundary is crossed.
Full API
| Method | Returns | Description |
|---|---|---|
advanceTime(options) | AdvanceTimeResponse — or { job_id, status } when async | Advance simulated time. Key fields: days_processed, diary_entries, wakeups_fired, consolidation counters. |
getAdvanceTimeJob(jobId) | { job_id, status, result?, error? } | Poll an async advance-time job. status is "running", "succeeded", or "failed". Job state has a 30-minute TTL. |
advanceTime options
| Field | Type | Required | Description |
|---|---|---|---|
agentId / agent_id | string | Yes | Agent UUID |
userId / user_id | string | Yes | User ID — must match the ID used during chat |
simulatedHours / simulated_hours | number | Yes | Hours to advance |
simulatedBaseOffsetHours / simulated_base_offset_hours | number | No | Hours already processed by prior calls in the same gap (default 0) |
runAsync / run_async / async | boolean | No | Return a job descriptor immediately instead of blocking (default false) |
Combines with other features
With Scheduled Reminders — fast-forwarding pending reminders
Any schedule whose next_fire_at falls within the advance window fires automatically. Advance 48 hours and two daily reminders will have fired — their intents processed, messages generated, and state updated — exactly as if real time had passed.
// Create a daily 09:00 reminder
await client.schedules.create("agent_abc", "user_123", {
cadence: { simple: { frequency: "daily", times: ["09:00"] }, timezone: "UTC" },
intent: "check in on how the user is feeling",
check_type: "reminder",
});
// Advance 48 hours — both 09:00 fires trigger inside the window
const result = await client.workbench.advanceTime({
agentId: "agent_abc",
userId: "user_123",
simulatedHours: 48,
});
console.log(result.wakeups_fired); // 2With Memory / Diary — replay compressed history
When time advances, a diary entry is generated for each simulated day. The agent "remembers" what happened during the gap — emotional tone, recurring themes, relationship developments — the same way it would after real days of conversation. Use this to give a new user a companion that already feels lived-in, or to let a character "grow" between chapters of a story.
With Wakeups — time-travel scheduled wakeups
Any wakeup scheduled with a scheduled_at inside the advance window fires during the advance, including its LLM-generated proactive message. This lets you test wakeup copy and timing without waiting for the real clock to reach the fire time.
Tutorials
Advance Time is a primitive that chains with scheduled reminders, wakeups, and memory. There is no standalone end-to-end tutorial yet. See the linked Mind Layer pages below for how it combines with other features.
Next steps
- Scheduled Reminders — schedules fire automatically during a time advance
- Memory — diary entries are generated for each simulated day in the window
- Evaluation — if you are using Advance Time for benchmarking, see the eval workflow
Also useful for evaluation
If you are running a benchmark suite, advanceTime lets you compress long-running scenarios into fast test runs. Advance a simulated week in seconds, inspect the diary entries and mood state, then score the result. Pair with the evaluation workflow to measure agent behavior quality after arbitrary amounts of simulated elapsed time.