Skip to content

Commit 749fb8a

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 ServiceName enum Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent 9ab513a commit 749fb8a

15 files changed

Lines changed: 1049 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: 10 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,17 @@ use trogon_std::env::SystemEnv;
119
use trogon_std::fs::SystemFs;
1210
use trogon_std::time::SystemClock;
1311

12+
use acp_telemetry::ServiceName;
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(
18+
&ServiceName::AcpNatsStdio,
19+
config.acp_prefix(),
20+
&SystemEnv,
21+
&SystemFs,
22+
);
1823
let config = config::apply_timeout_overrides(config, &SystemEnv);
1924

2025
info!("ACP bridge starting");
@@ -32,7 +37,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
3237
info!("ACP bridge stopped");
3338
}
3439

35-
telemetry::shutdown_otel();
40+
acp_telemetry::shutdown_otel();
3641

3742
result
3843
}
@@ -100,7 +105,7 @@ async fn run_bridge(
100105
}
101106
}
102107
}
103-
_ = signal::shutdown_signal() => {
108+
_ = acp_telemetry::signal::shutdown_signal() => {
104109
info!("ACP bridge shutting down (signal received)");
105110
Ok(())
106111
}
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)