Skip to content

Commit b80fbb7

Browse files
authored
fix(app-server): suppress TUI rollback warning (#30124)
## Why The TUI uses `thread/rollback` internally for user-facing flows such as prompt cancellation/backtracking. After `thread/rollback` was marked deprecated, those internal calls started surfacing `deprecationNotice` messages in the TUI, even though the user did not explicitly call the deprecated app-server API. The endpoint should remain deprecated for external app-server clients, but the built-in `codex-tui` client should not show this implementation-detail warning during normal interaction. ## What changed - Pass the initialized app-server client name into the `thread/rollback` request processor. - Suppress the `thread/rollback` deprecation notice only for `codex-tui`. - Preserve the existing `deprecationNotice` behavior for non-TUI clients. - Add regression coverage for the `codex-tui` suppression path. ## How to Test 1. Start Codex TUI from this branch. 2. Type text into the composer and press `Esc` to cancel/backtrack. 3. Confirm the TUI restores/cancels the prompt without showing `thread/rollback is deprecated and will be removed soon`. 4. Also verify an external app-server client that calls `thread/rollback` still receives `deprecationNotice`. Targeted tests: - `just test -p codex-app-server thread_rollback` - `just argument-comment-lint`
1 parent c9e6d97 commit b80fbb7

3 files changed

Lines changed: 50 additions & 3 deletions

File tree

codex-rs/app-server/src/message_processor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ impl MessageProcessor {
12051205
}
12061206
ClientRequest::ThreadRollback { params, .. } => {
12071207
self.thread_processor
1208-
.thread_rollback(&request_id, params)
1208+
.thread_rollback(&request_id, params, app_server_client_name.as_deref())
12091209
.await
12101210
}
12111211
ClientRequest::ThreadList { params, .. } => {

codex-rs/app-server/src/request_processors/thread_processor.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_WORKSPACE;
88

99
const THREAD_LIST_DEFAULT_LIMIT: usize = 25;
1010
const THREAD_LIST_MAX_LIMIT: usize = 100;
11+
const CODEX_TUI_CLIENT_NAME: &str = "codex-tui";
1112
const THREAD_ROLLBACK_DEPRECATION_SUMMARY: &str =
1213
"thread/rollback is deprecated and will be removed soon";
1314

@@ -634,9 +635,12 @@ impl ThreadRequestProcessor {
634635
&self,
635636
request_id: &ConnectionRequestId,
636637
params: ThreadRollbackParams,
638+
app_server_client_name: Option<&str>,
637639
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
638-
self.send_thread_rollback_deprecation_notice(request_id.connection_id)
639-
.await;
640+
if app_server_client_name != Some(CODEX_TUI_CLIENT_NAME) {
641+
self.send_thread_rollback_deprecation_notice(request_id.connection_id)
642+
.await;
643+
}
640644
self.thread_rollback_inner(request_id, params)
641645
.await
642646
.map(|()| None)

codex-rs/app-server/tests/suite/v2/thread_rollback.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use app_test_support::TestAppServer;
33
use app_test_support::create_final_assistant_message_sse_response;
44
use app_test_support::create_mock_responses_server_sequence_unchecked;
55
use app_test_support::to_response;
6+
use codex_app_server_protocol::ClientInfo;
67
use codex_app_server_protocol::DeprecationNoticeNotification;
78
use codex_app_server_protocol::JSONRPCMessage;
89
use codex_app_server_protocol::JSONRPCResponse;
@@ -24,6 +25,48 @@ use tokio::time::timeout;
2425

2526
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
2627

28+
#[tokio::test]
29+
async fn thread_rollback_does_not_emit_deprecation_notice_to_codex_tui() -> Result<()> {
30+
let codex_home = TempDir::new()?;
31+
let mut mcp = TestAppServer::new_with_auto_env(codex_home.path()).await?;
32+
let initialized = timeout(
33+
DEFAULT_READ_TIMEOUT,
34+
mcp.initialize_with_client_info(ClientInfo {
35+
name: "codex-tui".to_string(),
36+
title: None,
37+
version: "0.1.0".to_string(),
38+
}),
39+
)
40+
.await??;
41+
let JSONRPCMessage::Response(_) = initialized else {
42+
panic!("expected initialize response, got {initialized:?}");
43+
};
44+
mcp.clear_message_buffer();
45+
46+
let rollback_id = mcp
47+
.send_thread_rollback_request(ThreadRollbackParams {
48+
thread_id: "00000000-0000-0000-0000-000000000001".to_string(),
49+
num_turns: 1,
50+
})
51+
.await?;
52+
loop {
53+
let message = timeout(DEFAULT_READ_TIMEOUT, mcp.read_next_message()).await??;
54+
match message {
55+
JSONRPCMessage::Notification(notification) => {
56+
assert_ne!(notification.method, "deprecationNotice");
57+
}
58+
JSONRPCMessage::Error(error) if error.id == RequestId::Integer(rollback_id) => {
59+
break;
60+
}
61+
message => {
62+
panic!("expected rollback error response, got {message:?}");
63+
}
64+
}
65+
}
66+
67+
Ok(())
68+
}
69+
2770
#[tokio::test]
2871
async fn thread_rollback_drops_last_turns_and_persists_to_rollout() -> Result<()> {
2972
// Three Codex turns hit the mock model (session start + two turn/start calls).

0 commit comments

Comments
 (0)