diff --git a/Cargo.lock b/Cargo.lock index fd3e6d0..71c5cc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1463,8 +1463,8 @@ dependencies = [ [[package]] name = "codex-agent-identity" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "base64 0.22.1", @@ -1483,7 +1483,7 @@ dependencies = [ [[package]] name = "codex-api" -version = "0.162.1" +version = "0.163.0" dependencies = [ "anyhow", "assert_matches", @@ -1565,8 +1565,8 @@ dependencies = [ [[package]] name = "codex-async-utils" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "rand 0.9.3", "tokio", @@ -1575,8 +1575,8 @@ dependencies = [ [[package]] name = "codex-aws-auth" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "aws-config", "aws-credential-types", @@ -1595,8 +1595,8 @@ dependencies = [ [[package]] name = "codex-build-info" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-install-context", "semver", @@ -1606,8 +1606,8 @@ dependencies = [ [[package]] name = "codex-client" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-http-client", "eventsource-stream", @@ -1621,8 +1621,8 @@ dependencies = [ [[package]] name = "codex-code-mode" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-code-mode-protocol", "codex-http-client", @@ -1632,6 +1632,7 @@ dependencies = [ "futures", "http-body-util", "prost", + "rand 0.9.3", "reqwest", "serde_json", "tokio", @@ -1644,8 +1645,8 @@ dependencies = [ [[package]] name = "codex-code-mode-protocol" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-protocol", "glob", @@ -1662,13 +1663,13 @@ dependencies = [ [[package]] name = "codex-collaboration-mode-templates" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" [[package]] name = "codex-config" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "base64 0.22.1", @@ -1714,8 +1715,8 @@ dependencies = [ [[package]] name = "codex-connectors" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "arc-swap", @@ -1736,8 +1737,8 @@ dependencies = [ [[package]] name = "codex-context-fragments" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-protocol", "codex-utils-string", @@ -1746,8 +1747,8 @@ dependencies = [ [[package]] name = "codex-core-plugin-common" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-utils-absolute-path", "semver", @@ -1758,8 +1759,8 @@ dependencies = [ [[package]] name = "codex-exec-server" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "arc-swap", "axum", @@ -1774,6 +1775,8 @@ dependencies = [ "codex-file-system", "codex-file-watcher", "codex-http-client", + "codex-linux-sandbox", + "codex-mxc-sandbox", "codex-network-proxy", "codex-otel", "codex-protocol", @@ -1808,13 +1811,14 @@ dependencies = [ "tracing", "url", "uuid", + "which", "windows-sys 0.61.2", ] [[package]] name = "codex-exec-server-protocol" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "base64 0.22.1", "codex-file-system", @@ -1830,8 +1834,8 @@ dependencies = [ [[package]] name = "codex-execpolicy" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "clap", @@ -1848,8 +1852,8 @@ dependencies = [ [[package]] name = "codex-extension-items" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-utils-absolute-path", "schemars 0.8.22", @@ -1860,8 +1864,8 @@ dependencies = [ [[package]] name = "codex-features" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-network-proxy", "codex-protocol", @@ -1874,8 +1878,8 @@ dependencies = [ [[package]] name = "codex-feedback" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "bytes", @@ -1899,8 +1903,8 @@ dependencies = [ [[package]] name = "codex-file-search" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "clap", @@ -1914,8 +1918,8 @@ dependencies = [ [[package]] name = "codex-file-system" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "bytes", "codex-protocol", @@ -1927,8 +1931,8 @@ dependencies = [ [[package]] name = "codex-file-watcher" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "notify", "tokio", @@ -1937,8 +1941,8 @@ dependencies = [ [[package]] name = "codex-git-utils" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "chrono", @@ -1964,8 +1968,8 @@ dependencies = [ [[package]] name = "codex-guardian-context" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-context-fragments", "codex-history", @@ -1976,8 +1980,8 @@ dependencies = [ [[package]] name = "codex-history" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-protocol", "schemars 0.8.22", @@ -1987,8 +1991,8 @@ dependencies = [ [[package]] name = "codex-http-client" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "bytes", "codex-utils-rustls-provider", @@ -2018,8 +2022,8 @@ dependencies = [ [[package]] name = "codex-install-context" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-utils-absolute-path", "codex-utils-home-dir", @@ -2030,8 +2034,8 @@ dependencies = [ [[package]] name = "codex-keyring-store" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "keyring", "secret-service", @@ -2039,10 +2043,34 @@ dependencies = [ "tracing", ] +[[package]] +name = "codex-linux-sandbox" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" +dependencies = [ + "clap", + "codex-install-context", + "codex-network-proxy", + "codex-process-hardening", + "codex-protocol", + "codex-sandboxing", + "codex-uds", + "codex-utils-absolute-path", + "globset", + "landlock", + "libc", + "rustix", + "seccompiler", + "serde", + "serde_json", + "sha2 0.10.9", + "url", +] + [[package]] name = "codex-login" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "base64 0.22.1", @@ -2077,8 +2105,8 @@ dependencies = [ [[package]] name = "codex-model-provider" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "chrono", "codex-agent-identity", @@ -2106,8 +2134,8 @@ dependencies = [ [[package]] name = "codex-model-provider-info" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-client", "codex-protocol", @@ -2120,8 +2148,8 @@ dependencies = [ [[package]] name = "codex-models-manager" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "chrono", "codex-http-client", @@ -2138,8 +2166,8 @@ dependencies = [ [[package]] name = "codex-mxc-sandbox" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "appcontainer_common", @@ -2159,8 +2187,8 @@ dependencies = [ [[package]] name = "codex-network-proxy" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "base64 0.22.1", @@ -2206,8 +2234,8 @@ dependencies = [ [[package]] name = "codex-otel" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "bytes", "chrono", @@ -2241,8 +2269,8 @@ dependencies = [ [[package]] name = "codex-plugin" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-config", "codex-core-plugin-common", @@ -2254,10 +2282,18 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "codex-process-hardening" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" +dependencies = [ + "libc", +] + [[package]] name = "codex-prompts" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "codex-collaboration-mode-templates", @@ -2273,8 +2309,8 @@ dependencies = [ [[package]] name = "codex-protocol" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "chardetng", "chrono", @@ -2316,8 +2352,8 @@ dependencies = [ [[package]] name = "codex-response-debug-context" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "base64 0.22.1", "codex-api", @@ -2327,8 +2363,8 @@ dependencies = [ [[package]] name = "codex-rollout" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "chrono", @@ -2358,8 +2394,8 @@ dependencies = [ [[package]] name = "codex-sandboxing" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "codex-mxc-sandbox", @@ -2384,8 +2420,8 @@ dependencies = [ [[package]] name = "codex-secrets" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "age", "anyhow", @@ -2403,8 +2439,8 @@ dependencies = [ [[package]] name = "codex-shell-command" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "base64 0.22.1", "codex-protocol", @@ -2424,8 +2460,8 @@ dependencies = [ [[package]] name = "codex-skills" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-protocol", "codex-shell-command", @@ -2441,8 +2477,8 @@ dependencies = [ [[package]] name = "codex-state" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "chrono", @@ -2466,16 +2502,16 @@ dependencies = [ [[package]] name = "codex-terminal-detection" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "tracing", ] [[package]] name = "codex-tools" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "bitflags 2.13.1", "codex-code-mode", @@ -2484,7 +2520,6 @@ dependencies = [ "codex-features", "codex-file-system", "codex-protocol", - "codex-utils-absolute-path", "codex-utils-output-truncation", "codex-utils-path-uri", "codex-utils-string", @@ -2493,14 +2528,13 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.18", - "tracing", "urlencoding", ] [[package]] name = "codex-uds" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "async-io", "libc", @@ -2512,8 +2546,8 @@ dependencies = [ [[package]] name = "codex-utils-absolute-path" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "dirs", "dunce", @@ -2524,8 +2558,8 @@ dependencies = [ [[package]] name = "codex-utils-cache" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "lru", "sha1 0.10.6", @@ -2534,8 +2568,8 @@ dependencies = [ [[package]] name = "codex-utils-home-dir" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-utils-absolute-path", "dirs", @@ -2543,8 +2577,8 @@ dependencies = [ [[package]] name = "codex-utils-image" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "base64 0.22.1", "codex-utils-cache", @@ -2557,8 +2591,8 @@ dependencies = [ [[package]] name = "codex-utils-output-truncation" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-protocol", "codex-utils-string", @@ -2567,8 +2601,8 @@ dependencies = [ [[package]] name = "codex-utils-path" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-utils-absolute-path", "dunce", @@ -2578,8 +2612,8 @@ dependencies = [ [[package]] name = "codex-utils-path-uri" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "base64 0.22.1", "codex-utils-absolute-path", @@ -2593,8 +2627,8 @@ dependencies = [ [[package]] name = "codex-utils-plugins" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-exec-server", "codex-exec-server-protocol", @@ -2606,13 +2640,13 @@ dependencies = [ [[package]] name = "codex-utils-process" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" [[package]] name = "codex-utils-pty" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "filedescriptor", @@ -2627,8 +2661,8 @@ dependencies = [ [[package]] name = "codex-utils-redacted-string" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "schemars 0.8.22", "serde", @@ -2636,21 +2670,21 @@ dependencies = [ [[package]] name = "codex-utils-rustls-provider" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "rustls", ] [[package]] name = "codex-utils-stream-parser" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" [[package]] name = "codex-utils-string" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "regex-lite", "serde", @@ -2659,13 +2693,13 @@ dependencies = [ [[package]] name = "codex-utils-template" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" [[package]] name = "codex-websocket-auth" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "clap", @@ -2680,8 +2714,8 @@ dependencies = [ [[package]] name = "codex-websocket-client" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-http-client", "futures", @@ -2694,8 +2728,8 @@ dependencies = [ [[package]] name = "codex-windows-sandbox" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "anyhow", "base64 0.22.1", @@ -2722,8 +2756,8 @@ dependencies = [ [[package]] name = "codex-workload-identity" -version = "0.162.1" -source = "git+https://github.com/openai/codex.git?rev=092d3acd6bec3e3a14bdc7e7a2810ab628ab759d#092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" +version = "0.163.0" +source = "git+https://github.com/openai/codex.git?rev=83086188ae0614bd882818ff1aa23f3194962012#83086188ae0614bd882818ff1aa23f3194962012" dependencies = [ "codex-http-client", "serde", @@ -4224,11 +4258,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] @@ -4238,11 +4270,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -5509,9 +5543,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" dependencies = [ "atomic-waker", "bytes", @@ -5524,7 +5558,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -5680,7 +5713,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.58.0", + "windows-core 0.62.2", ] [[package]] @@ -8006,14 +8039,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.15" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" +checksum = "a9746dbde176634f4f2f1faf2404e30a31b2bc1e9cafb5329c95d8177a18c9fc" dependencies = [ "bytes", - "getrandom 0.3.4", + "getrandom 0.4.2", "lru-slab", - "rand 0.9.3", + "rand 0.10.1", + "rand_pcg", "ring", "rustc-hash", "rustls", @@ -8466,6 +8500,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "rand_regex" version = "0.18.1" @@ -8698,8 +8741,8 @@ dependencies = [ [[package]] name = "rmcp" -version = "3.3.0" -source = "git+https://github.com/modelcontextprotocol/rust-sdk?rev=3e636cab26c013eca5131103c03d20237f12c4df#3e636cab26c013eca5131103c03d20237f12c4df" +version = "3.5.1" +source = "git+https://github.com/modelcontextprotocol/rust-sdk?rev=4048ac40e958fb1a7d614617a2ae8d26666ee2fa#4048ac40e958fb1a7d614617a2ae8d26666ee2fa" dependencies = [ "base64 0.23.0", "chrono", @@ -8720,8 +8763,8 @@ dependencies = [ [[package]] name = "rmcp-macros" -version = "3.3.0" -source = "git+https://github.com/modelcontextprotocol/rust-sdk?rev=3e636cab26c013eca5131103c03d20237f12c4df#3e636cab26c013eca5131103c03d20237f12c4df" +version = "3.5.1" +source = "git+https://github.com/modelcontextprotocol/rust-sdk?rev=4048ac40e958fb1a7d614617a2ae8d26666ee2fa#4048ac40e958fb1a7d614617a2ae8d26666ee2fa" dependencies = [ "darling 0.24.0", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index c23498c..6c9e04a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ license = "Apache-2.0" rust-version = "1.95" [dependencies] -codex-context-fragments = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-websocket-client = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } +codex-context-fragments = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-websocket-client = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } tokio-tungstenite = "0.28" zstd = "0.13" anyhow = "1" @@ -30,22 +30,22 @@ opentelemetry = "0.31" opentelemetry_sdk = "0.31" opentelemetry-otlp = { version = "0.31", default-features = false, features = ["trace", "metrics", "logs", "http-proto", "reqwest-blocking-client", "reqwest-rustls"] } uuid = { version = "1", features = ["v4", "v5"] } -codex-api = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-client = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-http-client = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-login = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-model-provider = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-model-provider-info = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-models-manager = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-protocol = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-config = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } +codex-api = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-client = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-http-client = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-login = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-model-provider = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-model-provider-info = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-models-manager = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-protocol = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-config = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } -codex-features = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } +codex-features = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } -codex-tools = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } +codex-tools = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } -codex-exec-server = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } +codex-exec-server = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } [dev-dependencies] opentelemetry_sdk = { version = "0.31", features = ["testing"] } diff --git a/NOTICE b/NOTICE index 6211f8e..d54b956 100644 --- a/NOTICE +++ b/NOTICE @@ -2,9 +2,9 @@ Codex Responses Gateway This project uses Rust crates from OpenAI Codex: https://github.com/openai/codex -Revision: 687a119f0fcaace47e1f1abcc77cec6c813fd6da +Revision: 83086188ae0614bd882818ff1aa23f3194962012 Copyright OpenAI. Licensed under the Apache License, Version 2.0. The vendored codex-api crate has small raw transport extensions documented in vendor/raw-transport.patch. src/lite_instructions.rs is copied from the same revision's -core/context/base_instructions.rs with its trait import adjusted. +core/context/base_instructions.rs with its trait import adjusted and unused matching helpers omitted. See Cargo.lock for additional third-party dependencies and their versions. diff --git a/README.md b/README.md index 2fa0356..a9eec12 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A gateway that uses your ChatGPT subscription through the Codex Rust libraries. Supports Responses, streaming, WebSocket, images, files, search and Realtime. -Built on Codex **0.162.1** and Rust **1.95.0**. +Built on Codex **0.163.0** and Rust **1.95.0**. The gateway loads your account's model catalog at startup, including `gpt-6-sol` and `gpt-6-luna` when available. Restart to refresh the catalog; diff --git a/baseline/codex-release.lock.json b/baseline/codex-release.lock.json index 1787617..414dc86 100644 --- a/baseline/codex-release.lock.json +++ b/baseline/codex-release.lock.json @@ -1,29 +1,29 @@ { "repository": "https://github.com/openai/codex.git", - "release": "0.162.1", - "tag": "rust-v0.162.1", - "tag_object": "7a078f6bb4ce0dc2a81408b334ce52979d92c603", - "commit": "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d", - "published_at": "2026-10-09T19:44:51Z", - "release_url": "https://github.com/openai/codex/releases/tag/rust-v0.162.1", + "release": "0.163.0", + "tag": "rust-v0.163.0", + "tag_object": "129b8ec7ee6f4511557a4856279f529025c25af4", + "commit": "83086188ae0614bd882818ff1aa23f3194962012", + "published_at": "2026-10-15T21:30:38Z", + "release_url": "https://github.com/openai/codex/releases/tag/rust-v0.163.0", "prerelease": false, "companions": [ { "asset": "bwrap-x86_64-unknown-linux-musl.tar.gz", - "url": "https://github.com/openai/codex/releases/download/rust-v0.162.1/bwrap-x86_64-unknown-linux-musl.tar.gz", - "sha256": "fa78980959466bd7a04643384c6293511f06a3140345c1237cfc75ccde7f3eea", + "url": "https://github.com/openai/codex/releases/download/rust-v0.163.0/bwrap-x86_64-unknown-linux-musl.tar.gz", + "sha256": "bcc196b1d25dc2c2b912dcedf780b562deb0552f3c50648761ced145c3466a23", "executable": "codex-resources/bwrap" }, { "asset": "codex-code-mode-host-x86_64-unknown-linux-musl.tar.gz", - "url": "https://github.com/openai/codex/releases/download/rust-v0.162.1/codex-code-mode-host-x86_64-unknown-linux-musl.tar.gz", - "sha256": "458239ea45c1fc508d89695f180ab352f2834709a8a46929a4466f4f04399ada", + "url": "https://github.com/openai/codex/releases/download/rust-v0.163.0/codex-code-mode-host-x86_64-unknown-linux-musl.tar.gz", + "sha256": "314263128ba6592e7e807c265deeaf928a692b72dcbfeb5e0b20c9423b703529", "executable": "codex-code-mode-host" } ], "binary": { "asset": "codex-x86_64-unknown-linux-musl.tar.gz", - "url": "https://github.com/openai/codex/releases/download/rust-v0.162.1/codex-x86_64-unknown-linux-musl.tar.gz", - "sha256": "86f268d81b898f3e144c5ecff2ad2fda2c5802e042d6195b72538fe0fa125057" + "url": "https://github.com/openai/codex/releases/download/rust-v0.163.0/codex-x86_64-unknown-linux-musl.tar.gz", + "sha256": "beb339e8ecd9ba057a6bb2dc81ad8ca474812edfbf0fc5056ca818797648dde4" } } diff --git a/docs/codex-models.md b/docs/codex-models.md index 85a30e3..e02fe38 100644 --- a/docs/codex-models.md +++ b/docs/codex-models.md @@ -5,9 +5,9 @@ | Query parameter | Type / behavior | | --- | --- | -| `client_version` | Optional string; defaults to `0.162.1`. At most 128 ASCII letters, digits, `.`, `-`, `_`, `+`. | +| `client_version` | Optional string; defaults to `0.163.0`. At most 128 ASCII letters, digits, `.`, `-`, `_`, `+`. | -Example: `/backend-api/codex/models?client_version=0.162.1`. +Example: `/backend-api/codex/models?client_version=0.163.0`. The original `ModelsClient` fetches the catalog using the gateway's subscription. The complete upstream JSON is preserved, including fields outside the pinned model schema: diff --git a/docs/codex-responses.md b/docs/codex-responses.md index 4ece386..1883852 100644 --- a/docs/codex-responses.md +++ b/docs/codex-responses.md @@ -19,6 +19,6 @@ Codex session/routing metadata is forwarded, including `session-id`, `thread-id` Always SSE with native event payloads, including unknown event fields. Unlike `/v1/responses`, this endpoint does not assemble or rewrite terminal `response.output`. The original Codex parser validates the stream; interrupted streams never become synthetic success responses. -Codex 0.162.1 performs remote compaction through native Responses using a `compaction_trigger` input item. The separate [compact facade](responses-compact.md) is for applications that want a single JSON result. +Codex 0.163.0 performs remote compaction through native Responses using a `compaction_trigger` input item. The separate [compact facade](responses-compact.md) is for applications that want a single JSON result. Local shell, filesystem, custom and MCP tools still execute in the calling Codex. Native [images](images-generations.md) and [standalone search](search.md) use their corresponding gateway routes. diff --git a/docs/common.md b/docs/common.md index 2583f52..f52ac53 100644 --- a/docs/common.md +++ b/docs/common.md @@ -67,4 +67,4 @@ Gateway errors use this shape; `message` describes the failure: Upstream HTTP failures preserve their status and body, which may be non-JSON, plus headers such as `Retry-After`; transparent native routes preserve all end-to-end headers. Once SSE or WebSocket starts, failures are conveyed as events or connection closure; HTTP 200 alone does not mean generation succeeded. -Public adapters reject unsupported parameters instead of silently pretending to implement them. Native Responses preserves unknown protocol fields; native images/search use the pinned Codex types. Compatibility targets Codex **0.162.1**, not every OpenAI service or future Codex release. +Public adapters reject unsupported parameters instead of silently pretending to implement them. Native Responses preserves unknown protocol fields; native images/search use the pinned Codex types. Compatibility targets Codex **0.163.0**, not every OpenAI service or future Codex release. diff --git a/docs/health.md b/docs/health.md index 1490127..4ea5a90 100644 --- a/docs/health.md +++ b/docs/health.md @@ -3,7 +3,7 @@ `GET /healthz` · No authentication, body or query parameters required. ```json -{"status":"ok","codex_release":"0.162.1","codex_revision":"092d3acd6bec3e3a14bdc7e7a2810ab628ab759d"} +{"status":"ok","codex_release":"0.163.0","codex_revision":"83086188ae0614bd882818ff1aa23f3194962012"} ``` HTTP 200 confirms the gateway is running and reports its pinned source version. It does not call the upstream or guarantee current subscription validity, quota or model availability. diff --git a/docs/index.md b/docs/index.md index 8ede395..0e1200e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,7 +2,7 @@ [Common rules](common.md) · [Native routing and credentials](native.md) · [Pinned inventory](../baseline/api-inventory.json) · [Official counterpart mapping](../baseline/openai-api-counterparts.json) -Each page describes one logical endpoint and its aliases. The inventory is a snapshot of first-party routes audited against Codex 0.155.1; the gateway now uses 0.162.1. Transparent forwarding does not establish entitlement or full public API compatibility. `field?` means optional/nullable in the inventory's client revision; server-owned and additional fields are preserved. +Each page describes one logical endpoint and its aliases. The inventory is a snapshot of first-party routes audited against Codex 0.155.1; the gateway now uses 0.163.0. Transparent forwarding does not establish entitlement or full public API compatibility. `field?` means optional/nullable in the inventory's client revision; server-owned and additional fields are preserved. ## Public adapters diff --git a/docs/models.md b/docs/models.md index 5a3b2de..c2b43b0 100644 --- a/docs/models.md +++ b/docs/models.md @@ -8,7 +8,7 @@ No request body or required query parameters. When `client_version` is present ( {"object":"list","data":[{"id":"gpt-5.5","object":"model","created":0,"owned_by":"openai"}]} ``` -At startup, the gateway fetches the current account catalog using Codex 0.162.1. Public Responses (HTTP and WebSocket) and compaction validate model names and capabilities against this snapshot, so newly available models such as `gpt-6-sol` and `gpt-6-luna` do not require a new bundled catalog. Restart the gateway to refresh it. +At startup, the gateway fetches the current account catalog using Codex 0.163.0. Public Responses (HTTP and WebSocket) and compaction validate model names and capabilities against this snapshot, so newly available models such as `gpt-6-sol` and `gpt-6-luna` do not require a new bundled catalog. Restart the gateway to refresh it. If fetching fails, times out (after at most 30 seconds), or returns an empty/invalid catalog, startup logs a warning and falls back to the pinned Codex bundled catalog. Models absent from that fallback remain unavailable through public Responses. This is not a complete image-model or OpenAI Platform model directory; image endpoints default to `gpt-image-2` separately. diff --git a/docs/native.md b/docs/native.md index d5c8b28..7098b36 100644 --- a/docs/native.md +++ b/docs/native.md @@ -1,6 +1,6 @@ # Native routing -The gateway uses Codex **0.162.1** and retains the native route inventory audited against **0.155.1**. Source anchors in the endpoint pages refer to that inventory snapshot; upgrading the client does not establish continued upstream availability for every server-owned route. See the [endpoint index](index.md), [source inventory](../baseline/api-inventory.json) and [official API comparison](../baseline/openai-api-counterparts.json). These routes relay server-owned contracts; account entitlement and upstream validation still apply. +The gateway uses Codex **0.163.0** and retains the native route inventory audited against **0.155.1**. Source anchors in the endpoint pages refer to that inventory snapshot; upgrading the client does not establish continued upstream availability for every server-owned route. See the [endpoint index](index.md), [source inventory](../baseline/api-inventory.json) and [official API comparison](../baseline/openai-api-counterparts.json). These routes relay server-owned contracts; account entitlement and upstream validation still apply. | Gateway prefix | Upstream prefix | | --- | --- | diff --git a/docs/realtime.md b/docs/realtime.md index c8a033d..2f7c7ff 100644 --- a/docs/realtime.md +++ b/docs/realtime.md @@ -7,6 +7,6 @@ **Response:** full-duplex Realtime JSON text and native binary/control frames. Event payloads, transcription events, errors and close behavior are relayed; no Responses event conversion is applied. The configured timeout is an idle timeout. -The upstream is `https://api.openai.com/v1/realtime`. Use `X-Codex-Gateway-Authorization` for the gateway key and `Authorization` for an API key when starting a direct session. Codex 0.162.1 requires an API key for its direct Realtime connection. Its existing WebRTC-call sideband explicitly supports the ChatGPT authorization used to create that call; ordinary gateway Bearer mode reuses the gateway subscription for this case. Subscription access to arbitrary new public Realtime sessions is not established by the source. +The upstream is `https://api.openai.com/v1/realtime`. Use `X-Codex-Gateway-Authorization` for the gateway key and `Authorization` for an API key when starting a direct session. Codex 0.163.0 requires an API key for its direct Realtime connection. Its existing WebRTC-call sideband explicitly supports the ChatGPT authorization used to create that call; ordinary gateway Bearer mode reuses the gateway subscription for this case. Subscription access to arbitrary new public Realtime sessions is not established by the source. [Pinned sideband authorization](https://github.com/openai/codex/blob/be2951ea34f0d295ed0becf97079f92fa5f6950e/codex-rs/core/src/client.rs#L412) · [Pinned direct-session gate](https://github.com/openai/codex/blob/be2951ea34f0d295ed0becf97079f92fa5f6950e/codex-rs/core/src/realtime_conversation.rs#L1773) · [Official WebSocket guide](https://developers.openai.com/api/docs/guides/voice-websockets?api=realtime) diff --git a/docs/responses.md b/docs/responses.md index 6b9741e..a96b496 100644 --- a/docs/responses.md +++ b/docs/responses.md @@ -35,7 +35,7 @@ Known reasoning efforts are `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `reasoning.generate_summary` is accepted as a deprecated alias of `summary`. Explicit `reasoning.context` values are preserved; `auto` and `current_turn` select regular Responses because Lite requires `all_turns`. Omitted/null context retains the Lite default of `all_turns` when the request uses Lite (and is omitted for regular requests). Requests containing hosted `web_search` always use regular Responses, where the hosted tool can execute. See the [SDK compatibility suite and parameter audit](sdk-compatibility.md). -Message inputs accept `role` (`user`, `assistant`, `system`, `developer`) and string or Codex content arrays. Public `system` messages are forwarded as `developer` messages because Codex rejects the `system` input role. Their content and position are preserved, and explicit top-level `instructions` retain their content and are prepended as a classified developer message, matching Codex 0.162.1 (for both standard and lite requests). Text and image content, reasoning, function/custom calls and their outputs, web-search calls and Codex compaction items are supported. Functions/custom tools run in the caller, which submits their outputs in the next request. +Message inputs accept `role` (`user`, `assistant`, `system`, `developer`) and string or Codex content arrays. Public `system` messages are forwarded as `developer` messages because Codex rejects the `system` input role. Their content and position are preserved, and explicit top-level `instructions` retain their content and are prepended as a classified developer message, matching Codex 0.163.0 (for both standard and lite requests). Text and image content, reasoning, function/custom calls and their outputs, web-search calls and Codex compaction items are supported. Functions/custom tools run in the caller, which submits their outputs in the next request. HTTP continuation requires complete input history. `previous_response_id`, `background`, temperature/sampling controls and other unlisted top-level fields are not implemented here. `max_output_tokens` does not cap generated output; clients requiring a hard limit must not rely on it. diff --git a/docs/upgrade-0.163.0-validation.md b/docs/upgrade-0.163.0-validation.md new file mode 100644 index 0000000..c160d76 --- /dev/null +++ b/docs/upgrade-0.163.0-validation.md @@ -0,0 +1,56 @@ +# Codex 0.163.0 upgrade validation + +- Remote default branch: `main`, fetched at `991fb8c3df34b42e67763eaf600a0c1f49b13838` (Codex 0.162.1). +- Upstream latest stable: `rust-v0.163.0`, published `2026-10-15T21:30:38Z`; GitHub release has `draft=false`, `prerelease=false`. Both `/releases/latest` and the first 100 releases were checked. +- Annotated tag object: `129b8ec7ee6f4511557a4856279f529025c25af4`; peeled commit: `83086188ae0614bd882818ff1aa23f3194962012`, independently checked with `git ls-remote` and the clean downloaded source's HEAD. +- No existing Codex upgrade PR was open (only unrelated Renovate configuration PR #1). +- Work performed on independent branch/worktree `chore/codex-0.163.0`, preserving the original checkout's uncommitted development changes. + +## Changes + +Updated direct Codex Cargo dependencies, all transitive Codex lockfile entries, the vendored crate and its upstream integration tests, runtime version/revision, release binaries and companion checksums, active documentation, and NOTICE. Updated `hyper` and `quinn-proto` to the versions in the upstream release lockfile. Historical API inventories and prior upgrade reports remain historical snapshots. + +Refreshed every vendored Rust source from the pinned release, then reapplied the existing raw-transport patch. The patch's content is unchanged apart from hunk offsets. New upstream SSE, WebSocket interruption and other transport changes are included. The lite instructions fragment retains the upstream role, kind, markers and body; unused upstream matching helpers remain omitted. Rust remains pinned to upstream's 1.95.0. Replaced an existing error-observation `map_err` with equivalent `inspect_err` to satisfy strict Clippy; error and usage-accounting behavior are preserved. + +## Validation + +Release binary and companions verified against the release SHA-256 digests; CLI reports `codex-cli 0.163.0`. + +Source audit passes: 68 pinned Codex git packages, 981 shared registry packages, 42 identical upstream source files and 5 identical upstream integration test files. The six deliberate modified source files exactly match `vendor/raw-transport.patch` (SHA-256 `b2b366d0466c52e18f80582277c856aca8822cf38e708da71cbdfc3dac2b9383`). Vendored dependency expansion was checked against upstream's workspace declarations. + +Full local validation logs are retained under `artifacts/maintenance-0.163.0/` in the isolated worktree. + +All final commands passed, with `CARGO_BUILD_JOBS=4`: + +```text +cargo fmt --all -- --check +cargo check --workspace --all-targets --locked +cargo clippy --workspace --all-targets --locked -- -D warnings +cargo setup +cargo test --workspace --locked +cargo test --locked --test gateway actual_ -- --ignored +cargo test --locked --test source_audit -- --ignored +``` + +Workspace: **295 passed, 0 failed, 12 ignored**. Explicit official CLI/Python SDK fixtures: **5 passed**. Explicit source audit: **1 passed**. Credential-dependent live tests and container build/smoke were not run locally; the PR's remote container CI remains required before merge. + +The initial lockfile check overlapped dependency resolution and was rerun after the lockfile was complete. An earlier compilation was interrupted to increase build concurrency. Strict Clippy initially found the error-observation style issue described above; all final checks passed after the fix. + +Final successful exit records and log SHA-256 digests: + +```text +fmt exit=0 2026-10-16T22:11:55Z +check exit=0 2026-10-16T22:12:13Z +clippy exit=0 2026-10-16T22:12:35Z +setup exit=0 2026-10-16T22:12:45Z +workspace exit=0 2026-10-16T22:19:43Z +compatibility exit=0 2026-10-16T22:22:43Z +source-audit exit=0 2026-10-16T22:22:56Z +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 fmt.log +bf03fe7e5f2c909fb3dbb87f1055189c3626575e3963e24f8496b87f79fb3fbc check.log +ec139379b9388519caae2fff77792b841e3cdfc22662970ae32aedc3eedefcaa clippy.log +3565fa18cf683be299575361d284d4f289ee400616dbbeb9eadbbc49860978b2 setup.log +ad3aaf8c4491db7b207fd487a34ed6d2ebd486eeb8a8a98c88ccfc224f5c1803 workspace.log +5f1e8e2535d1ff72d0acd30cbe47573d7251c2c60d5135bf13f5d28f7aa17c88 compatibility.log +549a44d09d4c046a93fa6f1f873ca8695a133297fe6372ad18c7bda54d7bbae3 source-audit.log +``` diff --git a/src/lib.rs b/src/lib.rs index d93f864..d3ba57e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,5 +19,5 @@ pub mod transfers; pub mod transport; pub mod websocket; -pub const CODEX_RELEASE: &str = "0.162.1"; -pub const CODEX_REV: &str = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d"; +pub const CODEX_RELEASE: &str = "0.163.0"; +pub const CODEX_REV: &str = "83086188ae0614bd882818ff1aa23f3194962012"; diff --git a/src/lite_instructions.rs b/src/lite_instructions.rs index 306c2f7..4ae0c64 100644 --- a/src/lite_instructions.rs +++ b/src/lite_instructions.rs @@ -1,4 +1,4 @@ -// Copied from Codex 0.162.1 core/context/base_instructions.rs; Apache-2.0. +// Adapted from Codex 0.163.0 core/src/context/base_instructions.rs; Apache-2.0. use codex_context_fragments::ContextualUserFragment; use codex_protocol::models::ContentItemKind; diff --git a/src/server.rs b/src/server.rs index 5d6e8c2..dfeeabc 100644 --- a/src/server.rs +++ b/src/server.rs @@ -396,9 +396,8 @@ async fn respond( usage.failure("upstream_timeout"); timeout_error() })? - .map_err(|e| { + .inspect_err(|e| { usage.failure(e.code); - e })?; let upstream_headers = forward_response_headers(&running.headers); let mut accumulator = crate::output::OutputAccumulator::default(); diff --git a/tests/cases/response_types.rs b/tests/cases/response_types.rs index 9d101aa..28f4c93 100644 --- a/tests/cases/response_types.rs +++ b/tests/cases/response_types.rs @@ -56,7 +56,7 @@ async fn actual_openai_sdk_response_types() { let expected_lite = is_lite && context == "all_turns"; assert!( row.1["input"][0]["type"] != "additional_tools", - "requests without tools omit additional_tools in Codex 0.162.1" + "requests without tools omit additional_tools in Codex 0.163.0" ); assert_eq!( row.0.contains_key("x-openai-internal-codex-responses-lite"), diff --git a/vendor/codex-api/Cargo.toml b/vendor/codex-api/Cargo.toml index ac710cf..a9545ed 100644 --- a/vendor/codex-api/Cargo.toml +++ b/vendor/codex-api/Cargo.toml @@ -1,7 +1,7 @@ -# Vendored from Codex rust-v0.162.1; workspace dependencies expanded. +# Vendored from Codex rust-v0.163.0; workspace dependencies expanded. [package] name = "codex-api" -version = "0.162.1" +version = "0.163.0" edition = "2024" license = "Apache-2.0" @@ -10,11 +10,11 @@ async-channel = { version = "2.3.1" } base64 = { version = "0.22.1" } bytes = { version = "1.10.1" } chrono = { version = "0.4.43" } -codex-client = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-http-client = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-protocol = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-utils-rustls-provider = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } -codex-websocket-client = { git = "https://github.com/openai/codex.git", rev = "092d3acd6bec3e3a14bdc7e7a2810ab628ab759d" } +codex-client = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-http-client = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-protocol = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-utils-rustls-provider = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } +codex-websocket-client = { git = "https://github.com/openai/codex.git", rev = "83086188ae0614bd882818ff1aa23f3194962012" } futures = { version = "0.3", default-features = false } http = { version = "1.3.1" } schemars = { version = "0.8.22" } diff --git a/vendor/codex-api/src/api_bridge.rs b/vendor/codex-api/src/api_bridge.rs index abf0bf0..98d8d17 100644 --- a/vendor/codex-api/src/api_bridge.rs +++ b/vendor/codex-api/src/api_bridge.rs @@ -29,6 +29,7 @@ pub fn map_api_error(err: ApiError) -> CodexErr { | ApiError::Api { .. } | ApiError::Stream(_) | ApiError::ContentFilter + | ApiError::ResponseIncomplete(_) | ApiError::ContextWindowExceeded | ApiError::QuotaExceeded | ApiError::UsageNotIncluded @@ -58,6 +59,9 @@ fn map_api_error_details(err: ApiError) -> CodexErr { } ApiError::Stream(msg) => CodexErr::Stream(msg), ApiError::ContentFilter => CodexErr::new(CodexErrorDetails::ContentFilter), + ApiError::ResponseIncomplete(incomplete) => { + CodexErr::new(CodexErrorDetails::ResponseIncomplete(incomplete)) + } ApiError::ServerOverloaded { .. } => CodexErr::ServerOverloaded, ApiError::FlexUnavailable => CodexErr::new(CodexErrorDetails::FlexUnavailable), ApiError::Api { status, message } => { diff --git a/vendor/codex-api/src/common.rs b/vendor/codex-api/src/common.rs index 42c9fec..1abc89c 100644 --- a/vendor/codex-api/src/common.rs +++ b/vendor/codex-api/src/common.rs @@ -409,12 +409,23 @@ pub fn create_text_param_for_request( }) } +/// Distinguishes draining a live response from abandoning obsolete work. +#[derive(Clone, Copy)] +pub enum ResponseInterrupt { + /// Drain normally, without validating or waiting for interruption acknowledgements. + Drain, + /// Skip undispatched work or retire its transport at the cleanup deadline. + /// Undispatched work ends without a completion event and leaves the socket reusable. + Cancel { deadline: tokio::time::Instant }, +} + pub struct ResponseStream { pub rx_event: mpsc::Receiver>, /// Server-assigned `x-request-id` response header, when present. pub upstream_request_id: Option, /// Requests a graceful interrupt. Keep consuming events through completion. - pub interrupt: Option>, + /// Only `Cancel` validates and waits for an interruption acknowledgement. + pub interrupt: Option>, } impl Stream for ResponseStream { diff --git a/vendor/codex-api/src/endpoint/responses_websocket.rs b/vendor/codex-api/src/endpoint/responses_websocket.rs index 2e40160..34eae64 100644 --- a/vendor/codex-api/src/endpoint/responses_websocket.rs +++ b/vendor/codex-api/src/endpoint/responses_websocket.rs @@ -1,5 +1,6 @@ use crate::auth::SharedAuthProvider; use crate::common::ResponseEvent; +use crate::common::ResponseInterrupt; use crate::common::ResponseStream; use crate::common::ResponsesWsRequest; use crate::common::SafetyBufferingTreatment; @@ -25,6 +26,7 @@ use http::StatusCode; use serde::Deserialize; use serde_json::Value; use serde_json::map::Map as JsonMap; +use std::future::Future; use std::sync::Arc; use std::sync::OnceLock; use std::time::Duration; @@ -293,14 +295,38 @@ impl ResponsesWebsocketConnection { .send(Ok(ResponseEvent::ServerReasoningIncluded(true))) .await; } + // Abandoned work has a cleanup deadline; ordinary steering preserves the response. + let interrupt = async move { + match rx_interrupt.await { + Ok(interrupt) => interrupt, + Err(_) => std::future::pending().await, + } + } + .shared(); + let interrupt_timeout = async { + match interrupt.clone().await { + ResponseInterrupt::Drain => std::future::pending().await, + ResponseInterrupt::Cancel { deadline } => { + tokio::time::sleep_until(deadline).await; + } + } + }; + tokio::pin!(interrupt_timeout); let mut guard = tokio::select! { biased; _ = tx_event.closed() => return, + () = &mut interrupt_timeout => { + let _ = tx_event.send(Err(ApiError::Stream( + "timed out draining interrupted response".into(), + ))).await; + return; + } guard = stream.lock() => guard, }; if tx_event.is_closed() { return; } + let mut completion = None; let result = { let Some(ws_stream) = guard.as_mut() else { let _ = tx_event @@ -321,8 +347,12 @@ impl ResponsesWebsocketConnection { telemetry, turn_state.as_deref(), &timing_log_context, - rx_interrupt, + interrupt.clone(), + &mut completion, ) => result, + () = &mut interrupt_timeout => Err(ApiError::Stream( + "timed out draining interrupted response".into(), + )), _ = tx_event.closed() => Err(ApiError::Stream( "response event consumer dropped".to_string(), )), @@ -335,7 +365,15 @@ impl ResponsesWebsocketConnection { let failed_stream = guard.take(); drop(guard); drop(failed_stream); - let _ = tx_event.send(Err(err)).await; + // Failed cancellation retires the socket while preserving any received + // completion and its usage for the abandoned classifier's cleanup. + let event = completion.map_or_else(|| Err(err), Ok); + let _ = tx_event.send(event).await; + } else if let Some(completed) = completion { + // The handshake is finished. Consumer backpressure must not let the + // interruption deadline discard completion or its usage accounting. + drop(guard); + let _ = tx_event.send(Ok(completed)).await; } } .instrument(current_span), @@ -718,6 +756,11 @@ fn map_wrapped_websocket_error_event( })) } +#[derive(Deserialize)] +struct InterruptAcknowledgement { + response_id: String, +} + #[allow(clippy::too_many_arguments)] async fn run_websocket_response_stream( ws_stream: &mut WsStream, @@ -727,10 +770,18 @@ async fn run_websocket_response_stream( telemetry: Option>, turn_state: Option<&OnceLock>, timing_log_context: &ResponsesWebsocketTimingLogContext, - interrupt: oneshot::Receiver<()>, + interrupt: impl Future + Clone + Unpin, + completion: &mut Option, ) -> Result<(), ApiError> { let mut last_server_model: Option = None; let mut safety_buffering_treatment = SafetyBufferingTreatment::default(); + if matches!( + interrupt.clone().now_or_never(), + Some(ResponseInterrupt::Cancel { .. }) + ) { + // No request reached the backend, so this socket is still reusable. + return Ok(()); + } send_websocket_request( ws_stream, request_text, @@ -741,15 +792,18 @@ async fn run_websocket_response_stream( .await?; // A response owns its interrupt, and create must be sent before interrupt. - let mut interrupt = interrupt.fuse(); + let mut interrupt_request = interrupt.clone().fuse(); + let mut interruption = None; let mut response_id = None; + let mut awaiting_interrupt_ack = false; loop { let poll_start = Instant::now(); let response = tokio::select! { response = tokio::time::timeout(idle_timeout, ws_stream.next()) => { response.map_err(|_| ApiError::Stream("idle timeout waiting for websocket".into())) } - Ok(()) = &mut interrupt, if response_id.is_some() => { + request = &mut interrupt_request, if response_id.is_some() => { + interruption = Some(request); send_websocket_request( ws_stream, serde_json::json!({ @@ -762,6 +816,7 @@ async fn run_websocket_response_stream( timing_log_context.connection_reused, ) .await?; + awaiting_interrupt_ack = matches!(request, ResponseInterrupt::Cancel { .. }); continue; } }; @@ -799,6 +854,34 @@ async fn run_websocket_response_stream( continue; } }; + if matches!(interruption, Some(ResponseInterrupt::Cancel { .. })) + && matches!( + event.kind(), + "response.interrupt.accepted" | "response.interrupt.failed" + ) + { + let acknowledgement: InterruptAcknowledgement = serde_json::from_str(&text) + .map_err(|_| { + ApiError::Stream("invalid interruption acknowledgement".into()) + })?; + if !awaiting_interrupt_ack + || response_id.as_ref() != Some(&acknowledgement.response_id) + { + return Err(ApiError::Stream( + "unexpected interruption acknowledgement".into(), + )); + } + if event.kind() == "response.interrupt.failed" { + return Err(ApiError::Stream( + "response interruption was rejected".into(), + )); + } + awaiting_interrupt_ack = false; + if completion.is_some() { + break; + } + continue; + } emit_responses_websocket_timing_event( event.kind(), text.as_str(), @@ -834,7 +917,16 @@ async fn run_websocket_response_stream( } continue; } - if let Some(model) = event.response_model() + let model = event.response_model(); + // Preserve terminal usage before any accompanying notification can block. + let event = match process_responses_event(event) { + Ok(Some(event @ ResponseEvent::Completed { .. })) => { + *completion = Some(event); + Ok(None) + } + event => event, + }; + if let Some(model) = model && last_server_model.as_deref() != Some(model.as_str()) { let _ = tx_event @@ -872,22 +964,36 @@ async fn run_websocket_response_stream( "response event consumer dropped".to_string(), )); } - match process_responses_event(event) { + match event { Ok(Some(event)) => { if let ResponseEvent::Created { response_id: id } = &event { response_id.clone_from(id); } - let is_completed = matches!(event, ResponseEvent::Completed { .. }); let _ = tx_event.send(Ok(event)).await; - if is_completed { - break; - } } Ok(None) => {} Err(error) => { return Err(error.into_api_error()); } } + if completion.is_some() { + if awaiting_interrupt_ack { + continue; + } + if matches!( + interrupt.clone().now_or_never(), + Some(ResponseInterrupt::Cancel { .. }) + ) { + break; + } + // Ordinary responses deliver completion before releasing the socket. + // Preserve it if cancellation wins while delivery is backpressured. + let permit = tx_event.reserve().await; + if let (Ok(permit), Some(event)) = (permit, completion.take()) { + permit.send(Ok(event)); + } + break; + } } Message::Binary(_) => { return Err(ApiError::Stream("unexpected binary websocket event".into())); @@ -1002,6 +1108,8 @@ mod tests { let api_request = ResponsesApiRequest { model: "gpt-test".to_string(), input: vec![ResponseItem::Message { + status: None, + encrypted_content: None, id: Some(ResponseItemId::with_suffix("msg", "1")), role: "user".to_string(), content: vec![ContentItem::InputText { diff --git a/vendor/codex-api/src/endpoint/search.rs b/vendor/codex-api/src/endpoint/search.rs index 2de48fe..502e264 100644 --- a/vendor/codex-api/src/endpoint/search.rs +++ b/vendor/codex-api/src/endpoint/search.rs @@ -157,6 +157,8 @@ mod tests { model: "gpt-test".to_string(), reasoning: None, input: Some(SearchInput::Items(vec![ResponseItem::Message { + status: None, + encrypted_content: None, id: Some(ResponseItemId::with_suffix("msg", "search")), role: "user".to_string(), content: vec![ diff --git a/vendor/codex-api/src/error.rs b/vendor/codex-api/src/error.rs index 2834137..6d98cd4 100644 --- a/vendor/codex-api/src/error.rs +++ b/vendor/codex-api/src/error.rs @@ -1,6 +1,7 @@ use crate::rate_limits::RateLimitError; use codex_client::TransportError; use codex_http_client::RetryAfter; +use codex_protocol::error::ResponseIncompleteError; use codex_protocol::protocol::MisalignmentErrorDetails; use http::StatusCode; use serde_json::Value; @@ -16,6 +17,8 @@ pub enum ApiError { Stream(String), #[error("stream error: Incomplete response returned, reason: content_filter")] ContentFilter, + #[error(transparent)] + ResponseIncomplete(Box), #[error("context window exceeded")] ContextWindowExceeded, #[error("quota exceeded")] diff --git a/vendor/codex-api/src/lib.rs b/vendor/codex-api/src/lib.rs index 76a2c67..859dbb3 100644 --- a/vendor/codex-api/src/lib.rs +++ b/vendor/codex-api/src/lib.rs @@ -40,6 +40,7 @@ pub use crate::common::ReasoningSummaryDelivery; pub use crate::common::ResponseCreateWsRequest; pub use crate::common::ResponseEvent; pub use crate::common::ResponseId; +pub use crate::common::ResponseInterrupt; pub use crate::common::ResponseStream; pub use crate::common::ResponsesApiRequest; pub use crate::common::ResponsesApiTools; diff --git a/vendor/codex-api/src/sse/responses.rs b/vendor/codex-api/src/sse/responses.rs index 78885f4..34d5511 100644 --- a/vendor/codex-api/src/sse/responses.rs +++ b/vendor/codex-api/src/sse/responses.rs @@ -11,6 +11,7 @@ use crate::telemetry::SseTelemetry; use codex_client::ByteStream; use codex_client::StreamResponse; use codex_protocol::ResponseUsageMetadata; +use codex_protocol::error::ResponseIncompleteError; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::ModelVerification; use codex_protocol::protocol::TokenUsage; @@ -429,8 +430,24 @@ pub fn process_responses_event( return Err(ResponsesEventError::Api(ApiError::ContentFilter)); } if reason != "interrupted" { - let message = format!("Incomplete response returned, reason: {reason}"); - return Err(ResponsesEventError::Api(ApiError::Stream(message))); + let response = event.response.as_ref(); + let response_id = response + .and_then(|response| response.get("id")) + .and_then(Value::as_str) + .map(str::to_owned); + let token_usage = response + .and_then(|response| response.get("usage")) + .and_then(|usage| { + serde_json::from_value::(usage.clone()).ok() + }) + .map(Into::into); + return Err(ResponsesEventError::Api(ApiError::ResponseIncomplete( + Box::new(ResponseIncompleteError { + reason: reason.to_string(), + response_id, + token_usage, + }), + ))); } } if let Some(resp_val) = event.response { @@ -639,7 +656,10 @@ async fn process_sse_with_treatment( Ok(None) => {} Err(error) => { let error = error.into_api_error(); - if matches!(error, ApiError::FlexUnavailable) { + if matches!( + error, + ApiError::FlexUnavailable | ApiError::ResponseIncomplete(_) + ) { let _ = tx_event.send(Err(error)).await; return; } @@ -770,6 +790,8 @@ mod tests { ] if start_content.is_empty() && text == "First result." && done_content == &vec![codex_protocol::models::ContentItem::OutputText { + annotations: None, + logprobs: None, text: "First result.".to_string() }]); } diff --git a/vendor/codex-api/tests/clients.rs b/vendor/codex-api/tests/clients.rs index b17da45..a7400d3 100644 --- a/vendor/codex-api/tests/clients.rs +++ b/vendor/codex-api/tests/clients.rs @@ -340,6 +340,8 @@ async fn responses_client_stream_request_preserves_item_ids() -> Result<()> { let request = ResponsesApiRequest { model: "gpt-test".into(), input: vec![ResponseItem::Message { + status: None, + encrypted_content: None, id: Some(ResponseItemId::with_suffix("msg", "1")), role: "user".into(), content: vec![ContentItem::InputText { text: "hi".into() }], @@ -394,6 +396,8 @@ async fn responses_client_stream_request_sends_routing_fields_ahead_of_large_inp let request = ResponsesApiRequest { model: "gpt-test".into(), input: vec![ResponseItem::Message { + status: None, + encrypted_content: None, id: None, role: "user".into(), content: vec![ContentItem::InputText { text: large_input }], @@ -604,6 +608,8 @@ async fn azure_store_sends_ids_and_headers() -> Result<()> { let request = ResponsesApiRequest { model: "gpt-test".into(), input: vec![ResponseItem::Message { + status: None, + encrypted_content: None, id: Some(ResponseItemId::with_suffix("msg", "1")), role: "user".into(), content: vec![ContentItem::InputText { text: "hi".into() }], diff --git a/vendor/raw-transport.patch b/vendor/raw-transport.patch index d593457..bafb654 100644 --- a/vendor/raw-transport.patch +++ b/vendor/raw-transport.patch @@ -319,7 +319,7 @@ body: EncodedJsonBody, --- a/src/endpoint/responses_websocket.rs +++ b/src/endpoint/responses_websocket.rs -@@ -407,6 +407,52 @@ +@@ -445,6 +445,52 @@ .await } @@ -372,7 +372,7 @@ /// Opens a WebSocket connection long enough to validate the upgrade response. /// /// The probe uses the same URL construction, headers, authentication, TLS, -@@ -492,26 +538,7 @@ +@@ -530,26 +576,7 @@ connector: &WebSocketConnector, turn_state: Option>>, ) -> Result<(WsStream, StatusCode, bool, Option), ApiError> { @@ -400,7 +400,7 @@ let reasoning_included = response.headers().contains_key(X_REASONING_INCLUDED_HEADER); let server_model = response -@@ -533,6 +560,35 @@ +@@ -571,6 +598,35 @@ reasoning_included, server_model, )) @@ -438,7 +438,7 @@ fn websocket_config() -> WebSocketConfig { --- a/src/lib.rs +++ b/src/lib.rs -@@ -54,11 +54,13 @@ +@@ -55,11 +55,13 @@ pub use crate::endpoint::ImagesClient; pub use crate::endpoint::MemoriesClient; pub use crate::endpoint::ModelsClient; @@ -452,7 +452,7 @@ pub use crate::endpoint::RealtimeSessionConfig; pub use crate::endpoint::RealtimeSessionMode; pub use crate::endpoint::RealtimeTranscriptState; -@@ -77,6 +79,7 @@ +@@ -78,6 +80,7 @@ pub use crate::error::ApiError; pub use crate::files::HostedFileUploadContext; pub use crate::files::OPENAI_FILE_UPLOAD_LIMIT_BYTES;