Multi-Granularity Rewind¶
Roll back agent state to a previous point in the journal. Unlike ReplayEngine (which reconstructs current state by replaying forward), RewindEngine lets you go backward — pick a point in history and selectively undo conversation, code/state changes, or both.
from promptise.runtime.journal import InMemoryJournal, RewindEngine, RewindMode
rewind = RewindEngine(journal)
# Preview first (dry-run)
plan = await rewind.plan(
process_id="support-bot",
target_entry_id="entry-42",
mode=RewindMode.CANCEL,
)
print(plan.entries_affected, plan.summary)
# Apply
result = await rewind.apply(
process_id="support-bot",
target_entry_id="entry-42",
mode=RewindMode.CONVERSATION_ONLY,
actor="alice@acme.com",
)
5 Rewind Modes¶
| Mode | What it does |
|---|---|
BOTH |
Full rollback — rewind conversation and context state to the target point. |
CONVERSATION_ONLY |
Restore the conversation buffer but keep tool results and state changes. Useful when the agent went off-rails in chat but accumulated useful work. |
CODE_ONLY |
Restore context state and tool results but keep the conversation. Useful to "undo" a tool call without losing the reasoning that led to it. |
SUMMARIZE |
Keep everything as-is but inject a summary of the skipped interval into the conversation as a system note. The agent remembers it tried something without re-running it. |
CANCEL |
Dry-run: return the plan without changing anything. Always safe. |
Non-destructive¶
Original journal entries never get deleted or edited. A rewind is recorded as a new rewind entry in the journal, so the history shows when a rollback happened, who triggered it, and which mode was used.
# The rewind entry data looks like:
{
"target_entry_id": "entry-42",
"mode": "conversation_only",
"actor": "alice@acme.com",
"entries_affected": 5,
"conversation_affected": 3,
"code_affected": 2,
}
plan() — preview before committing¶
Always preview first:
plan = await rewind.plan(
process_id="support-bot",
target_entry_id="entry-42",
)
print(plan.entries_affected) # 5
print(plan.conversation_entries_affected) # 3
print(plan.code_entries_affected) # 2
print(plan.summary) # human-readable summary
Show the plan to a user or operator, let them pick a mode, then apply.
Entry type classification¶
The rewind engine classifies journal entries into two buckets:
Conversation entries: user_prompt, assistant_message, conversation_turn
Code/state entries: tool_call, tool_result, file_write, file_change, code_execution, context_update, state_transition
CONVERSATION_ONLY drops conversation entries after the target but keeps code entries. CODE_ONLY does the reverse. BOTH drops everything after the target.
Related¶
- Journal Backends — InMemoryJournal, FileJournal
- Replay Engine — forward recovery from checkpoints
- Agent Processes — lifecycle and state management