QoderSDKClient.rewind_files(user_message_id, ...) to roll back tracked files to the state they were in when a particular user message started processing.
These two capabilities must be used together: without enable_file_checkpointing=True, rewind_files() has no file snapshots to use.
Enabling File Checkpoint
enable_file_checkpointing is a field on QoderAgentOptions. To enable subsequent rewinds, use QoderSDKClient to keep the same active session and turn on checkpointing in options:
extra_args={"replay-user-messages": None} is not the switch that enables checkpointing. Its purpose is to replay UserMessage events in the response stream, carrying the uuid that can serve as a rewind anchor. If your application needs the user to click “go back to before this turn,” you typically set both.
Obtaining the Checkpoint ID
rewind_files() uses the user message ID as its anchor. The common pattern in the Python SDK is to capture this ID from UserMessage.uuid in the response stream:
checkpoint_id is the user message’s uuid — not the session_id, and not the ResultMessage ID. It is only valid in the session context that produced the checkpoint; other sessions cannot use this ID to rewind directly.
Dry Run Preview
Before executing a rewind, it is recommended to preview the impact withdry_run=True. A dry run does not modify files, making it suitable for confirmation dialogs or audit logs.
RewindFilesResult contains these fields:
| Field | Type | Description |
|---|---|---|
canRewind | bool | Whether the rewind can be performed. Dry run does not throw on failure; this field signals the result |
error | str | Diagnostic message when canRewind=False |
filesChanged | list[str] | List of file paths that will be reverted, or have already been reverted |
insertions | int | Total inserted lines that the rewind will undo (aggregate) |
deletions | int | Total deleted lines that the rewind will undo (aggregate) |
filesChanged, then combine it with your own workspace diff logic for display.
Executing Rewind
Once you have confirmed the impact scope, omitdry_run to execute the rewind:
filesChanged.
Failure Semantics
| Call form | Behavior when rewind is not possible |
|---|---|
await client.rewind_files(id, dry_run=True) | Returns {"canRewind": False, "error": ...}, suitable for direct diagnostic display |
await client.rewind_files(id) | Raises an exception; the caller should catch it and display the failure reason |
enable_file_checkpointing is not enabled, the supplied ID is not a valid user message UUID, the ID does not belong to the current session, or the target message has no rewindable file snapshots.
Settings Relationship
QoderAgentOptions.settings can be used together with enable_file_checkpointing:
enable_file_checkpointing=True, the SDK merges general.fileCheckpointing.enabled = True into the settings passed to the CLI. Other settings fields are preserved; if a fileCheckpointing configuration already exists, enabled is taken from the SDK option.
Boundaries
- Only local file checkpoints are rewound; external side effects from MCP tools, remote services, or databases are not undone.
- File changes made by writing files directly through
Bashare not treated as rewindable file snapshots. - File contents can be restored; directory-level side effects such as directory creation may not be undone.
- The checkpoint ID is bound to the session. After resuming the same session, the corresponding ID can still be used; it cannot be mixed across different sessions.
Field Reference
| Entry point | Type | Description | |
|---|---|---|---|
QoderAgentOptions.enable_file_checkpointing | `bool | None` | Enables file checkpoint for use with rewind_files() |
QoderAgentOptions.extra_args | `dict[str, str | None]` | Pass {"replay-user-messages": None} to receive UserMessage.uuid in the stream |
QoderSDKClient.rewind_files(user_message_id, dry_run=False) | async method | Preview or execute file rewind |
Best Practices
- Save the user message UUID: Bind
UserMessage.uuidto your UI’s message records, instead of looking them up by text. - Dry run before executing: Show the affected files and statistics first, then have the user confirm the rewind.
- Refresh UI after rewind: Reload relevant file state based on
filesChanged. - Show
erroron failure: Theerrorreturned by dry run is typically suitable as user-visible diagnostics.