pub mod anthropic;
pub mod google;
pub mod health;
pub mod openai;
pub mod passthrough;
use crate::ProxyState;
use axum::body::Bytes;
use axum::extract::DefaultBodyLimit;
use axum::extract::State;
use axum::http::{HeaderMap, Uri};
use axum::response::Response;
use axum::routing::{any, get, post};
use axum::Router;
const MAX_BODY_SIZE: usize = 200 * 1024 * 1024;
async fn messages_fallback_handler(
state: State<ProxyState>,
uri: Uri,
headers: HeaderMap,
body: Bytes,
) -> Response {
let query = uri.query().map(|q| format!("?{}", q)).unwrap_or_default();
let rewritten: Uri = format!("/v1/messages{}", query)
.parse()
.expect("/v1/messages is a valid URI");
anthropic::anthropic_handler(state, rewritten, headers, body).await
}
async fn responses_fallback_handler(
state: State<ProxyState>,
uri: Uri,
headers: HeaderMap,
body: Bytes,
) -> Response {
let query = uri.query().map(|q| format!("?{}", q)).unwrap_or_default();
let rewritten: Uri = format!("/v1/responses{}", query)
.parse()
.expect("/v1/responses is a valid URI");
openai::openai_handler(state, rewritten, headers, body).await
}
pub fn build_router(state: ProxyState) -> Router {
Router::new()
.route("/health", get(health::health_handler))
.route("/stats", get(health::stats_handler))
.route("/v1/messages", post(anthropic::anthropic_handler))
.route("/v1/chat/completions", post(openai::openai_handler))
.route("/v1/responses", post(openai::openai_handler))
.route("/messages", post(messages_fallback_handler))
.route("/responses", post(responses_fallback_handler))
.route("/v1beta/models/{*path}", post(google::google_handler))
.route("/v1/models/{*path}", post(google::google_handler))
.fallback(any(passthrough::passthrough_handler))
.layer(DefaultBodyLimit::max(MAX_BODY_SIZE))
.with_state(state)
}