Skip to content

Commit 02b8649

Browse files
committed
feat(acp-nats-ws): add WebSocket-to-NATS bridge binary crate
Introduce `acp-nats-ws`, a WebSocket endpoint that bridges ACP JSON-RPC messages to NATS for browser-based and remote clients. - Multiple concurrent WebSocket connections, each with its own ACP session on a dedicated single-threaded LocalSet - Duplex-pipe adapter: WS text frames ↔ newline-delimited JSON-RPC byte stream consumed by AgentSideConnection - Inbound frame sanitization: strip trailing CR/LF, validate UTF-8 on binary frames - Graceful shutdown: SIGINT/SIGTERM → broadcast → per-connection drain → join connection thread before telemetry teardown - Extract shared `acp-telemetry` crate from duplicated telemetry/signal modules in acp-nats-stdio and acp-nats-ws, parameterized by service name Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent 9ab513a commit 02b8649

14 files changed

Lines changed: 995 additions & 48 deletions

File tree

rsworkspace/Cargo.lock

Lines changed: 166 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rsworkspace/crates/acp-nats-stdio/Cargo.toml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@ edition = "2024"
55

66
[dependencies]
77
acp-nats = { path = "../acp-nats" }
8+
acp-telemetry = { path = "../acp-telemetry" }
89
agent-client-protocol = "0.9.4"
910
async-compat = "0.2.5"
1011
async-nats = "0.45.0"
1112
clap = { version = "4.5", features = ["derive", "env"] }
1213
opentelemetry = "0.31.0"
13-
opentelemetry-appender-tracing = "0.31.0"
14-
opentelemetry-otlp = { version = "0.31.0", features = ["http-json", "logs", "metrics", "reqwest-rustls"] }
15-
opentelemetry_sdk = { version = "0.31.0", features = ["rt-tokio", "logs", "metrics"] }
1614
trogon-std = { path = "../trogon-std" }
1715
tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "signal", "io-std"] }
1816
tracing = "0.1.44"
19-
tracing-opentelemetry = "0.32.1"
20-
tracing-subscriber = { version = "0.3.22", features = ["env-filter", "fmt", "json"] }
2117

2218
[dev-dependencies]
19+
tracing-subscriber = { version = "0.3.22", features = ["fmt"] }
2320
trogon-std = { path = "../trogon-std", features = ["test-support"] }

rsworkspace/crates/acp-nats-stdio/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
mod config;
2-
mod signal;
3-
mod telemetry;
42

53
use acp_nats::{StdJsonSerialize, agent::Bridge, client, nats};
64
use agent_client_protocol::AgentSideConnection;
@@ -11,10 +9,12 @@ use trogon_std::env::SystemEnv;
119
use trogon_std::fs::SystemFs;
1210
use trogon_std::time::SystemClock;
1311

12+
const SERVICE_NAME: &str = "acp-nats-stdio";
13+
1414
#[tokio::main]
1515
async fn main() -> Result<(), Box<dyn std::error::Error>> {
1616
let config = config::base_config(&SystemEnv)?;
17-
telemetry::init_logger(config.acp_prefix(), &SystemEnv, &SystemFs);
17+
acp_telemetry::init_logger(SERVICE_NAME, config.acp_prefix(), &SystemEnv, &SystemFs);
1818
let config = config::apply_timeout_overrides(config, &SystemEnv);
1919

2020
info!("ACP bridge starting");
@@ -32,7 +32,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3232
info!("ACP bridge stopped");
3333
}
3434

35-
telemetry::shutdown_otel();
35+
acp_telemetry::shutdown_otel();
3636

3737
result
3838
}
@@ -100,7 +100,7 @@ async fn run_bridge(
100100
}
101101
}
102102
}
103-
_ = signal::shutdown_signal() => {
103+
_ = acp_telemetry::signal::shutdown_signal() => {
104104
info!("ACP bridge shutting down (signal received)");
105105
Ok(())
106106
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "acp-nats-ws"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
acp-nats = { path = "../acp-nats" }
8+
acp-telemetry = { path = "../acp-telemetry" }
9+
agent-client-protocol = "0.9.4"
10+
async-compat = "0.2.5"
11+
async-nats = "0.45.0"
12+
axum = { version = "0.8.8", features = ["ws"] }
13+
clap = { version = "4.5", features = ["derive", "env"] }
14+
futures-util = { version = "0.3", features = ["sink"] }
15+
opentelemetry = "0.31.0"
16+
tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "signal", "net", "sync", "io-util"] }
17+
tower-http = { version = "0.6.8", features = ["trace"] }
18+
tracing = "0.1.44"
19+
trogon-std = { path = "../trogon-std" }
20+
21+
[dev-dependencies]
22+
tracing-subscriber = { version = "0.3.22", features = ["fmt"] }
23+
trogon-std = { path = "../trogon-std", features = ["test-support"] }

0 commit comments

Comments
 (0)