mirror of
https://github.com/openai/codex.git
synced 2026-04-29 02:41:12 +03:00
feat(app-server): thread/rollback API (#8454)
Add `thread/rollback` to app-server to support IDEs undo-ing the last N turns of a thread. For context, an IDE partner will be supporting an "undo" capability where the IDE (the app-server client) will be responsible for reverting the local changes made during the last turn. To support this well, we also need a way to drop the last turn (or more generally, the last N turns) from the agent's context. This is what `thread/rollback` does. **Core idea**: A Thread rollback is represented as a persisted event message (EventMsg::ThreadRollback) in the rollout JSONL file, not by rewriting history. On resume, both the model's context (core replay) and the UI turn list (app-server v2's thread history builder) apply these markers so the pruned history is consistent across live conversations and `thread/resume`. Implementation notes: - Rollback only affects agent context and appends to the rollout file; clients are responsible for reverting files on disk. - If a thread rollback is currently in progress, subsequent `thread/rollback` calls are rejected. - Because we use `CodexConversation::submit` and codex core tracks active turns, returning an error on concurrent rollbacks is communicated via an `EventMsg::Error` with a new variant `CodexErrorInfo::ThreadRollbackFailed`. app-server watches for that and sends the BAD_REQUEST RPC response. Tests cover thread rollbacks in both core and app-server, including when `num_turns` > existing turns (which clears all turns). **Note**: this explicitly does **not** behave like `/undo` which we just removed from the CLI, which does the opposite of what `thread/rollback` does. `/undo` reverts local changes via ghost commits/snapshots and does not modify the agent's context / conversation history.
This commit is contained in:
@@ -210,6 +210,12 @@ pub enum Op {
|
||||
/// Request Codex to undo a turn (turn are stacked so it is the same effect as CMD + Z).
|
||||
Undo,
|
||||
|
||||
/// Request Codex to drop the last N user turns from in-memory context.
|
||||
///
|
||||
/// This does not attempt to revert local filesystem changes. Clients are
|
||||
/// responsible for undoing any edits on disk.
|
||||
ThreadRollback { num_turns: u32 },
|
||||
|
||||
/// Request a code review from the agent.
|
||||
Review { review_request: ReviewRequest },
|
||||
|
||||
@@ -541,6 +547,9 @@ pub enum EventMsg {
|
||||
/// Conversation history was compacted (either automatically or manually).
|
||||
ContextCompacted(ContextCompactedEvent),
|
||||
|
||||
/// Conversation history was rolled back by dropping the last N user turns.
|
||||
ThreadRolledBack(ThreadRolledBackEvent),
|
||||
|
||||
/// Agent has started a task
|
||||
TaskStarted(TaskStartedEvent),
|
||||
|
||||
@@ -718,6 +727,7 @@ pub enum CodexErrorInfo {
|
||||
ResponseTooManyFailedAttempts {
|
||||
http_status_code: Option<u16>,
|
||||
},
|
||||
ThreadRollbackFailed,
|
||||
Other,
|
||||
}
|
||||
|
||||
@@ -1618,6 +1628,12 @@ pub struct UndoCompletedEvent {
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct ThreadRolledBackEvent {
|
||||
/// Number of user turns that were removed from context.
|
||||
pub num_turns: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
|
||||
pub struct StreamErrorEvent {
|
||||
pub message: String,
|
||||
|
||||
Reference in New Issue
Block a user