diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index d83626c4b7..ee3dd9d1e1 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -423,7 +423,7 @@ dependencies = [ "objc2-foundation", "parking_lot", "percent-encoding", - "windows-sys 0.60.2", + "windows-sys 0.59.0", "wl-clipboard-rs", "x11rb", ] @@ -1205,6 +1205,7 @@ dependencies = [ "tokio-tungstenite", "tokio-util", "tracing", + "tungstenite", "url", "wiremock", ] @@ -2961,7 +2962,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3206,7 +3207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3403,6 +3404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" dependencies = [ "crc32fast", + "libz-sys", "miniz_oxide", ] @@ -3871,6 +3873,30 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "headers" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64 0.22.1", + "bytes", + "headers-core", + "http 1.4.0", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.4.0", +] + [[package]] name = "heck" version = "0.5.0" @@ -4123,7 +4149,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -4594,7 +4620,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4856,6 +4882,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-sys" +version = "1.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-keyutils" version = "0.2.4" @@ -5301,7 +5338,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5444,7 +5481,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64 0.22.1", + "base64 0.21.7", "chrono", "getrandom 0.2.17", "http 1.4.0", @@ -5858,7 +5895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.45.0", ] [[package]] @@ -6370,7 +6407,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.6.2", + "socket2 0.5.10", "thiserror 2.0.18", "tokio", "tracing", @@ -6407,9 +6444,9 @@ dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.6.2", + "socket2 0.5.10", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -7238,7 +7275,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8604,7 +8641,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.3", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8947,8 +8984,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.28.0" -source = "git+https://github.com/JakkuSakura/tokio-tungstenite?rev=2ae536b0de793f3ddf31fc2f22d445bf1ef2023d#2ae536b0de793f3ddf31fc2f22d445bf1ef2023d" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" dependencies = [ "futures-util", "log", @@ -9342,11 +9380,13 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.28.0" -source = "git+https://github.com/JakkuSakura/tungstenite-rs?rev=f514de8644821113e5d18a027d6d28a5c8cc0a6e#f514de8644821113e5d18a027d6d28a5c8cc0a6e" +version = "0.27.0" +source = "git+https://github.com/signalapp/tungstenite-rs?rev=ebdbe86da4c2e5502044658b872189b0c8f63468#ebdbe86da4c2e5502044658b872189b0c8f63468" dependencies = [ "bytes", "data-encoding", + "flate2", + "headers", "http 1.4.0", "httparse", "log", @@ -9956,7 +9996,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 39ebe5967d..d05c761e9c 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -226,7 +226,11 @@ tiny_http = "0.12" tokio = "1" tokio-stream = "0.1.18" tokio-test = "0.4" -tokio-tungstenite = { version = "0.28.0", features = ["proxy", "rustls-tls-native-roots"] } +tokio-tungstenite = { version = "0.27.0", features = ["rustls-tls-native-roots"] } +# +# Enable permessage-deflate support by unifying tungstenite features across the +# graph. codex-api references deflate config via tokio-tungstenite's re-export. +tungstenite = { version = "0.27.0", features = ["deflate"] } tokio-util = "0.7.18" toml = "0.9.5" toml_edit = "0.24.0" @@ -317,10 +321,7 @@ opt-level = 0 # ratatui = { path = "../../ratatui" } crossterm = { git = "https://github.com/nornagon/crossterm", branch = "nornagon/color-query" } ratatui = { git = "https://github.com/nornagon/ratatui", branch = "nornagon-v0.29.0-patch" } -tokio-tungstenite = { git = "https://github.com/JakkuSakura/tokio-tungstenite", rev = "2ae536b0de793f3ddf31fc2f22d445bf1ef2023d" } +tungstenite = { git = "https://github.com/signalapp/tungstenite-rs", rev = "ebdbe86da4c2e5502044658b872189b0c8f63468" } # Uncomment to debug local changes. # rmcp = { path = "../../rust-sdk/crates/rmcp" } - -[patch."ssh://git@github.com/JakkuSakura/tungstenite-rs.git"] -tungstenite = { git = "https://github.com/JakkuSakura/tungstenite-rs", rev = "f514de8644821113e5d18a027d6d28a5c8cc0a6e" } diff --git a/codex-rs/codex-api/Cargo.toml b/codex-rs/codex-api/Cargo.toml index 761e572369..8fb67621fa 100644 --- a/codex-rs/codex-api/Cargo.toml +++ b/codex-rs/codex-api/Cargo.toml @@ -16,6 +16,7 @@ serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["macros", "net", "rt", "sync", "time"] } tokio-tungstenite = { workspace = true } +tungstenite = { workspace = true } tracing = { workspace = true } eventsource-stream = { workspace = true } regex-lite = { workspace = true } diff --git a/codex-rs/codex-api/src/endpoint/responses_websocket.rs b/codex-rs/codex-api/src/endpoint/responses_websocket.rs index 20c6067b17..9f361183cc 100644 --- a/codex-rs/codex-api/src/endpoint/responses_websocket.rs +++ b/codex-rs/codex-api/src/endpoint/responses_websocket.rs @@ -30,6 +30,9 @@ use tracing::debug; use tracing::error; use tracing::info; use tracing::trace; +use tungstenite::extensions::ExtensionsConfig; +use tungstenite::extensions::compression::deflate::DeflateConfig; +use tungstenite::protocol::WebSocketConfig; use url::Url; type WsStream = WebSocketStream>; @@ -170,7 +173,9 @@ async fn connect_websocket( .map_err(|err| ApiError::Stream(format!("failed to build websocket request: {err}")))?; request.headers_mut().extend(headers); - let response = tokio_tungstenite::connect_async(request).await; + let response = + tokio_tungstenite::connect_async_with_config(request, Some(websocket_config()), false) + .await; let (stream, response) = match response { Ok((stream, response)) => { @@ -203,6 +208,26 @@ async fn connect_websocket( Ok((stream, reasoning_included, models_etag)) } +fn websocket_config() -> WebSocketConfig { + let mut extensions = ExtensionsConfig::default(); + extensions.permessage_deflate = Some(DeflateConfig::default()); + + let mut config = WebSocketConfig::default(); + config.extensions = extensions; + config +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn websocket_config_enables_permessage_deflate() { + let config = websocket_config(); + assert!(config.extensions.permessage_deflate.is_some()); + } +} + fn map_ws_error(err: WsError, url: &Url) -> ApiError { match err { WsError::Http(response) => {