From 2f4225b453be7dad25b0a18817a5c8528d6b9067 Mon Sep 17 00:00:00 2001 From: Michael Yuan Date: Fri, 23 Jan 2026 23:59:17 +0000 Subject: [PATCH 1/4] Fix deprecation warnings and add aarch64 build support - Remove usage of deprecated realtime_ws module from main.rs - Add #![allow(deprecated)] to realtime_ws.rs for internal usage - Add RUSTFLAGS with fp16 target feature for aarch64 builds in CI - Update README with aarch64 build instructions Co-Authored-By: Claude Opus 4.5 --- .github/workflows/release.yml | 1 + README.md | 6 ++++++ src/main.rs | 24 ++---------------------- src/services/realtime_ws.rs | 2 ++ 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 12ace76..4d10a29 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,6 +108,7 @@ jobs: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc PKG_CONFIG_ALLOW_CROSS: "1" PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig + RUSTFLAGS: "-C target-feature=+fp16" run: cargo build --release --target aarch64-unknown-linux-gnu - name: Package release artifact diff --git a/README.md b/README.md index 415132e..a69042e 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,12 @@ Edit `config.toml` to customize the VAD, ASR, LLM, TTS services, as well as prom cargo build --release ``` +**Note for aarch64 (ARM64) builds:** If building on or for aarch64 Linux, you may need to enable the fp16 target feature: + +``` +RUSTFLAGS="-C target-feature=+fp16" cargo build --release +``` + ### Configure AI services The `config.toml` can use any combination of open-source or proprietary AI services, as long as they offer OpenAI-compatible API endpoints. Here are instructions to start open source AI servers for the EchoKit server. diff --git a/src/main.rs b/src/main.rs index 97d6f4a..0e2322a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,6 @@ use axum::{ use clap::Parser; use config::Config; -use crate::{config::ASRConfig, services::realtime_ws::StableRealtimeConfig}; pub mod ai; pub mod config; @@ -55,23 +54,14 @@ async fn routes( }); let mut tool_set = ai::openai::tool::ToolSet::default(); - let mut real_config: Option = None; // todo: support other configs match &config.config { config::AIConfig::Stable { llm: config::LLMConfig::OpenAIChat(chat_llm), - tts, - asr, + tts: _, + asr: _, } => { - if let ASRConfig::Whisper(asr) = asr { - real_config = Some(StableRealtimeConfig { - llm: chat_llm.clone(), - tts: tts.clone(), - asr: asr.clone(), - }); - } - for server in &chat_llm.mcp_server { match server.type_ { config::MCPType::SSE => { @@ -173,16 +163,6 @@ async fn routes( ))) .layer(axum::Extension(record_config.clone())); - if let Some(real_config) = real_config { - log::info!( - "Adding realtime WebSocket handler with config: {:?}", - real_config - ); - router = router - .route("/v1/realtime", any(services::realtime_ws::ws_handler)) - .layer(axum::Extension(Arc::new(real_config))); - } - router.route( "/version", get(|| async { diff --git a/src/services/realtime_ws.rs b/src/services/realtime_ws.rs index 282730f..e648f0f 100644 --- a/src/services/realtime_ws.rs +++ b/src/services/realtime_ws.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use axum::{ extract::{Extension, WebSocketUpgrade, ws::WebSocket}, response::IntoResponse, From d6ebf49b5a822739f0651bbbf0c62cdebdfd3f1f Mon Sep 17 00:00:00 2001 From: Michael Yuan Date: Sat, 24 Jan 2026 01:53:59 +0000 Subject: [PATCH 2/4] Add aarch64 build job to CI workflow Co-Authored-By: Claude Opus 4.5 --- .github/workflows/rust_ci.yml | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/.github/workflows/rust_ci.yml b/.github/workflows/rust_ci.yml index c017764..81a25dd 100644 --- a/.github/workflows/rust_ci.yml +++ b/.github/workflows/rust_ci.yml @@ -41,3 +41,48 @@ jobs: - name: Build binary run: cargo build --release + + build-aarch64: + name: Build (aarch64) + runs-on: ubuntu-latest + container: + image: debian:bookworm-slim + steps: + - name: Install base dependencies + shell: bash + run: | + set -euo pipefail + export DEBIAN_FRONTEND=noninteractive + dpkg --add-architecture arm64 + apt-get update + apt-get install -y --no-install-recommends \ + ca-certificates \ + pkg-config \ + libssl-dev \ + libssl-dev:arm64 \ + gcc-aarch64-linux-gnu \ + libc6-dev-arm64-cross \ + build-essential \ + git \ + curl \ + unzip \ + cmake + + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Add Rust target + run: rustup target add aarch64-unknown-linux-gnu + + - name: Build binary + env: + CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc + AR_aarch64_unknown_linux_gnu: aarch64-linux-gnu-ar + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc + PKG_CONFIG_ALLOW_CROSS: "1" + PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig + RUSTFLAGS: "-C target-feature=+fp16" + run: cargo build --release --target aarch64-unknown-linux-gnu From 7162ce4b819b7b3c1990cf6aa481c4e5cda6a822 Mon Sep 17 00:00:00 2001 From: Michael Yuan Date: Sat, 24 Jan 2026 02:02:03 +0000 Subject: [PATCH 3/4] Move aarch64 rustflags to .cargo/config.toml - Add .cargo/config.toml with fp16 target feature for aarch64 - Remove RUSTFLAGS from CI workflows (now handled by cargo config) - Update README to reflect the change Co-Authored-By: Claude Opus 4.5 --- .cargo/config.toml | 2 ++ .github/workflows/release.yml | 1 - .github/workflows/rust_ci.yml | 1 - README.md | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..afcb428 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.aarch64-unknown-linux-gnu] +rustflags = ["-C", "target-feature=+fp16"] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d10a29..12ace76 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,7 +108,6 @@ jobs: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc PKG_CONFIG_ALLOW_CROSS: "1" PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig - RUSTFLAGS: "-C target-feature=+fp16" run: cargo build --release --target aarch64-unknown-linux-gnu - name: Package release artifact diff --git a/.github/workflows/rust_ci.yml b/.github/workflows/rust_ci.yml index 81a25dd..a41be93 100644 --- a/.github/workflows/rust_ci.yml +++ b/.github/workflows/rust_ci.yml @@ -84,5 +84,4 @@ jobs: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc PKG_CONFIG_ALLOW_CROSS: "1" PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig - RUSTFLAGS: "-C target-feature=+fp16" run: cargo build --release --target aarch64-unknown-linux-gnu diff --git a/README.md b/README.md index a69042e..ceef3f6 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Edit `config.toml` to customize the VAD, ASR, LLM, TTS services, as well as prom cargo build --release ``` -**Note for aarch64 (ARM64) builds:** If building on or for aarch64 Linux, you may need to enable the fp16 target feature: +**Note for aarch64 (ARM64) builds:** When cross-compiling for aarch64, the required `fp16` target feature is automatically enabled via `.cargo/config.toml`. If building natively on aarch64, you may need to set: ``` RUSTFLAGS="-C target-feature=+fp16" cargo build --release From b1cb21120eadd48151a7fec077cd2ec532923e14 Mon Sep 17 00:00:00 2001 From: Michael Yuan Date: Sat, 24 Jan 2026 02:16:11 +0000 Subject: [PATCH 4/4] Restore realtime router with #[allow(deprecated)] Keep the /v1/realtime endpoint functional while suppressing deprecation warnings with targeted #[allow(deprecated)] attributes. Co-Authored-By: Claude Opus 4.5 --- src/main.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0e2322a..eea9bca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,8 @@ use axum::{ use clap::Parser; use config::Config; +#[allow(deprecated)] +use crate::{config::ASRConfig, services::realtime_ws::StableRealtimeConfig}; pub mod ai; pub mod config; @@ -54,14 +56,25 @@ async fn routes( }); let mut tool_set = ai::openai::tool::ToolSet::default(); + #[allow(deprecated)] + let mut real_config: Option = None; // todo: support other configs + #[allow(deprecated)] match &config.config { config::AIConfig::Stable { llm: config::LLMConfig::OpenAIChat(chat_llm), - tts: _, - asr: _, + tts, + asr, } => { + if let ASRConfig::Whisper(asr) = asr { + real_config = Some(StableRealtimeConfig { + llm: chat_llm.clone(), + tts: tts.clone(), + asr: asr.clone(), + }); + } + for server in &chat_llm.mcp_server { match server.type_ { config::MCPType::SSE => { @@ -163,6 +176,17 @@ async fn routes( ))) .layer(axum::Extension(record_config.clone())); + #[allow(deprecated)] + if let Some(real_config) = real_config { + log::info!( + "Adding realtime WebSocket handler with config: {:?}", + real_config + ); + router = router + .route("/v1/realtime", any(services::realtime_ws::ws_handler)) + .layer(axum::Extension(Arc::new(real_config))); + } + router.route( "/version", get(|| async {