From 268328001f899ec02cebab238fdeafda052525b6 Mon Sep 17 00:00:00 2001 From: Owen Lin Date: Thu, 25 Jun 2026 10:15:46 -0700 Subject: [PATCH] chore(app-server): mark thread/rollback as deprecated (#29928) We will drop support for this in the near future due to the complexity it introduces. --- .../schema/json/ClientRequest.json | 1 + .../codex_app_server_protocol.schemas.json | 1 + .../codex_app_server_protocol.v2.schemas.json | 1 + .../schema/json/v2/ThreadRollbackParams.json | 1 + .../typescript/v2/ThreadRollbackParams.ts | 3 +++ .../src/protocol/v2/thread.rs | 1 + codex-rs/app-server/README.md | 2 +- codex-rs/app-server/src/request_processors.rs | 1 + .../request_processors/thread_processor.rs | 16 +++++++++++++++ .../tests/suite/v2/thread_rollback.rs | 20 +++++++++++++++++++ 10 files changed, 46 insertions(+), 1 deletion(-) diff --git a/codex-rs/app-server-protocol/schema/json/ClientRequest.json b/codex-rs/app-server-protocol/schema/json/ClientRequest.json index 0027988c4..acfffc370 100644 --- a/codex-rs/app-server-protocol/schema/json/ClientRequest.json +++ b/codex-rs/app-server-protocol/schema/json/ClientRequest.json @@ -4174,6 +4174,7 @@ "type": "object" }, "ThreadRollbackParams": { + "description": "DEPRECATED: `thread/rollback` will be removed soon.", "properties": { "numTurns": { "description": "The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes.", diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 33981b5b5..8625c08da 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -18997,6 +18997,7 @@ }, "ThreadRollbackParams": { "$schema": "http://json-schema.org/draft-07/schema#", + "description": "DEPRECATED: `thread/rollback` will be removed soon.", "properties": { "numTurns": { "description": "The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes.", diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 5a7cf80e8..94fb8a989 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -16776,6 +16776,7 @@ }, "ThreadRollbackParams": { "$schema": "http://json-schema.org/draft-07/schema#", + "description": "DEPRECATED: `thread/rollback` will be removed soon.", "properties": { "numTurns": { "description": "The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes.", diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackParams.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackParams.json index cb3ba0db3..aa52fbd59 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadRollbackParams.json @@ -1,5 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "description": "DEPRECATED: `thread/rollback` will be removed soon.", "properties": { "numTurns": { "description": "The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes.", diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadRollbackParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadRollbackParams.ts index 1c938e3bf..af416d187 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadRollbackParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadRollbackParams.ts @@ -2,6 +2,9 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +/** + * DEPRECATED: `thread/rollback` will be removed soon. + */ export type ThreadRollbackParams = { threadId: string, /** * The number of turns to drop from the end of the thread. Must be >= 1. diff --git a/codex-rs/app-server-protocol/src/protocol/v2/thread.rs b/codex-rs/app-server-protocol/src/protocol/v2/thread.rs index c330c7eef..0be777627 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/thread.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/thread.rs @@ -1025,6 +1025,7 @@ pub struct ThreadBackgroundTerminalsTerminateResponse { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] +/// DEPRECATED: `thread/rollback` will be removed soon. pub struct ThreadRollbackParams { pub thread_id: String, /// The number of turns to drop from the end of the thread. Must be >= 1. diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index 397fa3d58..4c88d4b69 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -167,7 +167,7 @@ Example with notification opt-out: - `thread/backgroundTerminals/clean` — terminate all running background terminals for a thread (experimental; requires `capabilities.experimentalApi`); returns `{}` when the cleanup request is accepted. - `thread/backgroundTerminals/list` — list running background terminals for a loaded thread (experimental; requires `capabilities.experimentalApi`); returns `data` with the running terminal ids. - `thread/backgroundTerminals/terminate` — terminate one running background terminal by app-server `processId` (experimental; requires `capabilities.experimentalApi`); returns whether a process was terminated. -- `thread/rollback` — drop the last N turns from the agent’s in-memory context and persist a rollback marker in the rollout so future resumes see the pruned history; returns the updated `thread` (with `turns` populated) on success. +- `thread/rollback` — deprecated and will be removed soon. Drop the last N turns from the agent’s in-memory context and persist a rollback marker in the rollout so future resumes see the pruned history; returns the updated `thread` (with `turns` populated) on success. - `turn/start` — add user input to a thread and begin Codex generation; responds with the initial `turn` object and streams `turn/started`, `item/*`, and `turn/completed` notifications. `clientUserMessageId` is optional; when supplied, the corresponding `userMessage` item echoes it as `clientId`. Experimental `runtimeWorkspaceRoots` replaces the thread-scoped runtime workspace roots used to materialize `:workspace_roots`; paths must be absolute. Prefer experimental `permissions` profile selection by id for permission overrides; the legacy `sandboxPolicy` field is still accepted but cannot be combined with `permissions`. For `collaborationMode`, `settings.developer_instructions: null` means "use built-in instructions for the selected mode". Deprecated experimental `multiAgentMode` is ignored; Ultra reasoning effort selects proactive behavior. - `thread/inject_items` — append raw Responses API items to a loaded thread’s model-visible history without starting a user turn; returns `{}` on success. - `turn/steer` — add user input to an already in-flight regular turn without starting a new turn; returns the active `turnId` that accepted the input. `clientUserMessageId` is optional; when supplied, the corresponding `userMessage` item echoes it as `clientId`. Review and manual compaction turns reject `turn/steer`. diff --git a/codex-rs/app-server/src/request_processors.rs b/codex-rs/app-server/src/request_processors.rs index 9b56957a5..57a65fd31 100644 --- a/codex-rs/app-server/src/request_processors.rs +++ b/codex-rs/app-server/src/request_processors.rs @@ -56,6 +56,7 @@ use codex_app_server_protocol::ConsumeAccountRateLimitResetCreditParams; use codex_app_server_protocol::ConsumeAccountRateLimitResetCreditResponse; use codex_app_server_protocol::ConversationGitInfo; use codex_app_server_protocol::ConversationSummary; +use codex_app_server_protocol::DeprecationNoticeNotification; use codex_app_server_protocol::DynamicToolFunctionSpec; use codex_app_server_protocol::DynamicToolNamespaceTool; use codex_app_server_protocol::DynamicToolSpec; diff --git a/codex-rs/app-server/src/request_processors/thread_processor.rs b/codex-rs/app-server/src/request_processors/thread_processor.rs index 7242e816b..ab4e24186 100644 --- a/codex-rs/app-server/src/request_processors/thread_processor.rs +++ b/codex-rs/app-server/src/request_processors/thread_processor.rs @@ -8,6 +8,8 @@ use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE; const THREAD_LIST_DEFAULT_LIMIT: usize = 25; const THREAD_LIST_MAX_LIMIT: usize = 100; +const THREAD_ROLLBACK_DEPRECATION_SUMMARY: &str = + "thread/rollback is deprecated and will be removed soon"; struct ThreadListFilters { model_providers: Option>, @@ -633,11 +635,25 @@ impl ThreadRequestProcessor { request_id: &ConnectionRequestId, params: ThreadRollbackParams, ) -> Result, JSONRPCErrorError> { + self.send_thread_rollback_deprecation_notice(request_id.connection_id) + .await; self.thread_rollback_inner(request_id, params) .await .map(|()| None) } + async fn send_thread_rollback_deprecation_notice(&self, connection_id: ConnectionId) { + self.outgoing + .send_server_notification_to_connections( + &[connection_id], + ServerNotification::DeprecationNotice(DeprecationNoticeNotification { + summary: THREAD_ROLLBACK_DEPRECATION_SUMMARY.to_string(), + details: None, + }), + ) + .await; + } + pub(crate) async fn thread_list( &self, params: ThreadListParams, diff --git a/codex-rs/app-server/tests/suite/v2/thread_rollback.rs b/codex-rs/app-server/tests/suite/v2/thread_rollback.rs index 9f0df0ff2..9481f6923 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_rollback.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_rollback.rs @@ -3,6 +3,8 @@ use app_test_support::TestAppServer; use app_test_support::create_final_assistant_message_sse_response; use app_test_support::create_mock_responses_server_sequence_unchecked; use app_test_support::to_response; +use codex_app_server_protocol::DeprecationNoticeNotification; +use codex_app_server_protocol::JSONRPCMessage; use codex_app_server_protocol::JSONRPCResponse; use codex_app_server_protocol::RequestId; use codex_app_server_protocol::ThreadItem; @@ -97,6 +99,7 @@ async fn thread_rollback_drops_last_turns_and_persists_to_rollout() -> Result<() mcp.read_stream_until_notification_message("turn/completed"), ) .await??; + mcp.clear_message_buffer(); // Roll back the last turn. let rollback_id = mcp @@ -105,6 +108,23 @@ async fn thread_rollback_drops_last_turns_and_persists_to_rollout() -> Result<() num_turns: 1, }) .await?; + let deprecation_notice = timeout(DEFAULT_READ_TIMEOUT, mcp.read_next_message()).await??; + let JSONRPCMessage::Notification(deprecation_notice) = deprecation_notice else { + panic!("thread/rollback should emit deprecationNotice before its response"); + }; + assert_eq!(deprecation_notice.method, "deprecationNotice"); + let deprecation_notice: DeprecationNoticeNotification = serde_json::from_value( + deprecation_notice + .params + .expect("deprecationNotice params should be present"), + )?; + assert_eq!( + deprecation_notice, + DeprecationNoticeNotification { + summary: "thread/rollback is deprecated and will be removed soon".to_string(), + details: None, + } + ); let rollback_resp: JSONRPCResponse = timeout( DEFAULT_READ_TIMEOUT, mcp.read_stream_until_response_message(RequestId::Integer(rollback_id)),