#[cfg(feature = "acp-http")]
use axum::Router;
#[cfg(feature = "acp-http")]
use axum::extract::DefaultBodyLimit;
#[cfg(feature = "acp-http")]
use axum::routing::{get, post};
#[cfg(feature = "acp-http")]
use tower_http::cors::CorsLayer;
#[cfg(feature = "acp-http")]
use crate::transport::auth::BearerAuthLayer;
#[cfg(feature = "acp-http")]
use crate::transport::crud::{
create_session_handler, delete_session_handler, get_session_handler, update_session_handler,
};
#[cfg(feature = "acp-http")]
use crate::transport::discovery::{agent_json_handler, discovery_handler};
#[cfg(feature = "acp-http")]
use crate::transport::http::{
AcpHttpState, get_handler, health_handler, list_sessions_handler, post_handler,
session_messages_handler,
};
#[cfg(feature = "acp-http")]
use crate::transport::ws::ws_upgrade_handler;
#[cfg(feature = "acp-http")]
const MAX_BODY_BYTES: usize = 1_048_576;
#[cfg(feature = "acp-http")]
#[cfg_attr(docsrs, doc(cfg(feature = "acp-http")))]
pub fn acp_router(state: AcpHttpState) -> Router {
let acp_routes = Router::new()
.route("/acp", post(post_handler).get(get_handler))
.route("/acp/ws", get(ws_upgrade_handler))
.route(
"/sessions",
get(list_sessions_handler).post(create_session_handler),
)
.route(
"/sessions/{id}",
get(get_session_handler)
.patch(update_session_handler)
.delete(delete_session_handler),
)
.route("/sessions/{id}/messages", get(session_messages_handler))
.layer(DefaultBodyLimit::max(MAX_BODY_BYTES))
.layer(CorsLayer::new());
let acp_routes = if let Some(token) = state.server_config.auth_bearer_token.clone() {
acp_routes.layer(BearerAuthLayer::new(token))
} else {
tracing::warn!(
"ACP HTTP server started without bearer token authentication; \
session history endpoints are publicly accessible"
);
acp_routes
};
let mut router = Router::new()
.route("/health", get(health_handler))
.merge(acp_routes);
if state.server_config.discovery_enabled {
router = router
.route("/.well-known/acp.json", get(discovery_handler))
.route("/agent.json", get(agent_json_handler));
}
router.with_state(state)
}