mirror of
https://github.com/openai/codex.git
synced 2026-04-30 19:32:04 +03:00
app-server: Replay pending item requests on thread/resume (#12560)
Replay pending client requests after `thread/resume` and emit resolved notifications when those requests clear so approval/input UI state stays in sync after reconnects and across subscribed clients. Affected RPCs: - `item/commandExecution/requestApproval` - `item/fileChange/requestApproval` - `item/tool/requestUserInput` Motivation: - Resumed clients need to see pending approval/input requests that were already outstanding before the reconnect. - Clients also need an explicit signal when a pending request resolves or is cleared so stale UI can be removed on turn start, completion, or interruption. Implementation notes: - Use pending client requests from `OutgoingMessageSender` in order to replay them after `thread/resume` attaches the connection, using original request ids. - Emit `serverRequest/resolved` when pending requests are answered or cleared by lifecycle cleanup. - Update the app-server protocol schema, generated TypeScript bindings, and README docs for the replay/resolution flow. High-level test plan: - Added automated coverage for replaying pending command execution and file change approval requests on `thread/resume`. - Added automated coverage for resolved notifications in command approval, file change approval, request_user_input, turn start, and turn interrupt flows. - Verified schema/docs updates in the relevant protocol and app-server tests. Manual testing: - Tested reconnect/resume with multiple connections. - Confirmed state stayed in sync between connections.
This commit is contained in:
committed by
GitHub
parent
66b0adb34c
commit
69d7a456bb
42
codex-rs/app-server/src/server_request_error.rs
Normal file
42
codex-rs/app-server/src/server_request_error.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
|
||||
pub(crate) const TURN_TRANSITION_PENDING_REQUEST_ERROR_REASON: &str = "turnTransition";
|
||||
|
||||
pub(crate) fn is_turn_transition_server_request_error(error: &JSONRPCErrorError) -> bool {
|
||||
error
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.get("reason"))
|
||||
.and_then(serde_json::Value::as_str)
|
||||
== Some(TURN_TRANSITION_PENDING_REQUEST_ERROR_REASON)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::is_turn_transition_server_request_error;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn turn_transition_error_is_detected() {
|
||||
let error = JSONRPCErrorError {
|
||||
code: -1,
|
||||
message: "client request resolved because the turn state was changed".to_string(),
|
||||
data: Some(json!({ "reason": "turnTransition" })),
|
||||
};
|
||||
|
||||
assert_eq!(is_turn_transition_server_request_error(&error), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unrelated_error_is_not_detected() {
|
||||
let error = JSONRPCErrorError {
|
||||
code: -1,
|
||||
message: "boom".to_string(),
|
||||
data: Some(json!({ "reason": "other" })),
|
||||
};
|
||||
|
||||
assert_eq!(is_turn_transition_server_request_error(&error), false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user