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.
This commit is contained in:
Owen Lin authored and GitHub committed 2026-06-25 17:15:46 +00:00
1 parent c38b2e9ba6
commit 268328001f
10 files changed
+46 -1

No files matched your search

@@ -4174,6 +4174,7 @@
"type": "object" "type": "object"
}, },
"ThreadRollbackParams": { "ThreadRollbackParams": {
"description": "DEPRECATED: `thread/rollback` will be removed soon.",
"properties": { "properties": {
"numTurns": { "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.", "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.",
@@ -18997,6 +18997,7 @@
}, },
"ThreadRollbackParams": { "ThreadRollbackParams": {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"description": "DEPRECATED: `thread/rollback` will be removed soon.",
"properties": { "properties": {
"numTurns": { "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.", "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.",
@@ -16776,6 +16776,7 @@
}, },
"ThreadRollbackParams": { "ThreadRollbackParams": {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"description": "DEPRECATED: `thread/rollback` will be removed soon.",
"properties": { "properties": {
"numTurns": { "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.", "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.",
@@ -1,5 +1,6 @@
{ {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"description": "DEPRECATED: `thread/rollback` will be removed soon.",
"properties": { "properties": {
"numTurns": { "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.", "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.",
@@ -2,6 +2,9 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. // 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, export type ThreadRollbackParams = { threadId: string,
/** /**
* The number of turns to drop from the end of the thread. Must be >= 1. * The number of turns to drop from the end of the thread. Must be >= 1.
@@ -1025,6 +1025,7 @@ pub struct ThreadBackgroundTerminalsTerminateResponse {
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")] #[ts(export_to = "v2/")]
/// DEPRECATED: `thread/rollback` will be removed soon.
pub struct ThreadRollbackParams { pub struct ThreadRollbackParams {
pub thread_id: String, pub thread_id: String,
/// The number of turns to drop from the end of the thread. Must be >= 1. /// The number of turns to drop from the end of the thread. Must be >= 1.
+1 -1
View File
@@ -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/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/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/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. - `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. - `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`. - `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`.
@@ -56,6 +56,7 @@ use codex_app_server_protocol::ConsumeAccountRateLimitResetCreditParams;
use codex_app_server_protocol::ConsumeAccountRateLimitResetCreditResponse; use codex_app_server_protocol::ConsumeAccountRateLimitResetCreditResponse;
use codex_app_server_protocol::ConversationGitInfo; use codex_app_server_protocol::ConversationGitInfo;
use codex_app_server_protocol::ConversationSummary; use codex_app_server_protocol::ConversationSummary;
use codex_app_server_protocol::DeprecationNoticeNotification;
use codex_app_server_protocol::DynamicToolFunctionSpec; use codex_app_server_protocol::DynamicToolFunctionSpec;
use codex_app_server_protocol::DynamicToolNamespaceTool; use codex_app_server_protocol::DynamicToolNamespaceTool;
use codex_app_server_protocol::DynamicToolSpec; use codex_app_server_protocol::DynamicToolSpec;
@@ -8,6 +8,8 @@ use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
const THREAD_LIST_DEFAULT_LIMIT: usize = 25; const THREAD_LIST_DEFAULT_LIMIT: usize = 25;
const THREAD_LIST_MAX_LIMIT: usize = 100; const THREAD_LIST_MAX_LIMIT: usize = 100;
const THREAD_ROLLBACK_DEPRECATION_SUMMARY: &str =
"thread/rollback is deprecated and will be removed soon";
struct ThreadListFilters { struct ThreadListFilters {
model_providers: Option<Vec<String>>, model_providers: Option<Vec<String>>,
@@ -633,11 +635,25 @@ impl ThreadRequestProcessor {
request_id: &ConnectionRequestId, request_id: &ConnectionRequestId,
params: ThreadRollbackParams, params: ThreadRollbackParams,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> { ) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
self.send_thread_rollback_deprecation_notice(request_id.connection_id)
.await;
self.thread_rollback_inner(request_id, params) self.thread_rollback_inner(request_id, params)
.await .await
.map(|()| None) .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( pub(crate) async fn thread_list(
&self, &self,
params: ThreadListParams, params: ThreadListParams,
@@ -3,6 +3,8 @@ use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response; use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked; use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response; 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::JSONRPCResponse;
use codex_app_server_protocol::RequestId; use codex_app_server_protocol::RequestId;
use codex_app_server_protocol::ThreadItem; 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"), mcp.read_stream_until_notification_message("turn/completed"),
) )
.await??; .await??;
mcp.clear_message_buffer();
// Roll back the last turn. // Roll back the last turn.
let rollback_id = mcp let rollback_id = mcp
@@ -105,6 +108,23 @@ async fn thread_rollback_drops_last_turns_and_persists_to_rollout() -> Result<()
num_turns: 1, num_turns: 1,
}) })
.await?; .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( let rollback_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT, DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(rollback_id)), mcp.read_stream_until_response_message(RequestId::Integer(rollback_id)),