From d44696065723a56b9de6538cd6348fcbe6c1542e Mon Sep 17 00:00:00 2001 From: Benjamin Carlsson Date: Fri, 21 Aug 2026 15:09:09 +0000 Subject: [PATCH] Support voice-aware configuration and version-skew builds (#39953) ## What changed - Add `chat.toggle_voice_mute` to the configurable TUI keymap and generated configuration schema. - Let the exec-server version-skew harness build the voice-enabled CLI on Debian-like Linux hosts without preinstalled development metadata by assembling a temporary package sysroot. - Preserve the existing build path on other Linux environments when the Debian package tools are unavailable. ## Testing - Add a shell test that verifies a non-Debian Linux environment without voice metadata still proceeds to the Cargo build. GitOrigin-RevId: 95c5ebc3f85d152a5217dee561286f2be662f79a --- codex-rs/config/src/tui_keymap.rs | 2 + codex-rs/core/config.schema.json | 14 +++++- .../exec-server/testing/run_version_skew.sh | 34 +++++++++++++++ .../testing/run_version_skew_test.sh | 43 +++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100755 codex-rs/exec-server/testing/run_version_skew_test.sh diff --git a/codex-rs/config/src/tui_keymap.rs b/codex-rs/config/src/tui_keymap.rs index 942bbaf4c8..7fe6572586 100644 --- a/codex-rs/config/src/tui_keymap.rs +++ b/codex-rs/config/src/tui_keymap.rs @@ -123,6 +123,8 @@ pub struct TuiGlobalKeymap { #[serde(deny_unknown_fields)] #[schemars(deny_unknown_fields)] pub struct TuiChatKeymap { + /// Toggle the microphone in an active voice conversation. + pub toggle_voice_mute: Option, /// Interrupt the active turn. pub interrupt_turn: Option, /// Decrease the active reasoning effort. diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index 5128c49fca..37189d57ed 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -3573,7 +3573,8 @@ "increase_reasoning_effort": null, "interrupt_turn": null, "next_permission_mode": null, - "previous_permission_mode": null + "previous_permission_mode": null, + "toggle_voice_mute": null }, "composer": { "history_search_next": null, @@ -3985,6 +3986,14 @@ } ], "description": "Switch to the previous available permission mode." + }, + "toggle_voice_mute": { + "allOf": [ + { + "$ref": "#/definitions/KeybindingsSpec" + } + ], + "description": "Toggle the microphone in an active voice conversation." } }, "type": "object" @@ -4329,7 +4338,8 @@ "increase_reasoning_effort": null, "interrupt_turn": null, "next_permission_mode": null, - "previous_permission_mode": null + "previous_permission_mode": null, + "toggle_voice_mute": null } }, "composer": { diff --git a/codex-rs/exec-server/testing/run_version_skew.sh b/codex-rs/exec-server/testing/run_version_skew.sh index f0e9536def..dd52dc63eb 100755 --- a/codex-rs/exec-server/testing/run_version_skew.sh +++ b/codex-rs/exec-server/testing/run_version_skew.sh @@ -29,6 +29,40 @@ case "$(uname -s):$(uname -m)" in esac asset="codex-${target}.tar.gz" + +if [[ "$(uname -s)" == "Linux" ]] \ + && command -v apt-get >/dev/null \ + && command -v dpkg-deb >/dev/null \ + && command -v dpkg-architecture >/dev/null \ + && ! pkg-config --exists alsa glib-2.0 gobject-2.0 gio-2.0; then + # Debian-like hosts can download development metadata without sudo. The + # temporary sysroot still relies on runtime libraries installed on the host. + voice_package_directory="${release_directory}/voice-packages" + voice_sysroot="${release_directory}/voice-sysroot" + mkdir -p "${voice_package_directory}" "${voice_sysroot}" + ( + cd "${voice_package_directory}" + apt-get download libasound2-dev libglib2.0-dev libcap-dev libffi-dev libmount-dev \ + libpcre2-dev libselinux1-dev zlib1g-dev libblkid-dev libsepol-dev + ) + for package in "${voice_package_directory}"/*.deb; do + dpkg-deb --extract "${package}" "${voice_sysroot}" + done + + voice_multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" + voice_library_directory="${voice_sysroot}/usr/lib/${voice_multiarch}" + for library in "${voice_library_directory}"/*.so; do + [[ -L "${library}" ]] || continue + library_target="$(readlink "${library}")" + if [[ ! -e "${voice_library_directory}/${library_target}" && -e "/usr/lib/${voice_multiarch}/${library_target}" ]]; then + ln -s "/usr/lib/${voice_multiarch}/${library_target}" "${voice_library_directory}/${library_target}" + fi + done + + export PKG_CONFIG_PATH="${voice_library_directory}/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}" + export PKG_CONFIG_SYSROOT_DIR="${voice_sysroot}" +fi + cd "${repo_root}/codex-rs" cargo build -p codex-cli --bin codex export CODEX_TEST_CURRENT_CODEX="${CARGO_TARGET_DIR:-${repo_root}/codex-rs/target}/debug/codex" diff --git a/codex-rs/exec-server/testing/run_version_skew_test.sh b/codex-rs/exec-server/testing/run_version_skew_test.sh new file mode 100755 index 0000000000..109a61cefa --- /dev/null +++ b/codex-rs/exec-server/testing/run_version_skew_test.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -euo pipefail + +script_directory="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +script_path="${script_directory}/run_version_skew.sh" +fake_bin="$(mktemp -d "${TMPDIR:-/tmp}/codex-version-skew-test.XXXXXX")" +trap 'rm -rf "${fake_bin:?}"' EXIT + +for tool in bash dirname mkdir mktemp rm sed; do + ln -s "$(command -v "${tool}")" "${fake_bin}/${tool}" +done + +printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'case "${1:-}" in' \ + ' -s) printf "Linux\\n" ;;' \ + ' -m) printf "x86_64\\n" ;;' \ + ' *) exit 1 ;;' \ + 'esac' >"${fake_bin}/uname" +chmod +x "${fake_bin}/uname" + +printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'exit 1' >"${fake_bin}/pkg-config" +chmod +x "${fake_bin}/pkg-config" + +printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'printf "reached cargo\\n" >&2' \ + 'exit 97' >"${fake_bin}/cargo" +chmod +x "${fake_bin}/cargo" + +set +e +output="$(PATH="${fake_bin}" "${script_path}" latest 2>&1)" +status=$? +set -e + +if [[ "${status}" -ne 97 || "${output}" != *"reached cargo"* ]]; then + printf '%s\n' "expected non-Debian Linux without voice metadata to reach cargo" >&2 + printf 'status: %s\n%s\n' "${status}" "${output}" >&2 + exit 1 +fi