modelmux/lib.rs
1//! # ModelMux - Vertex AI to OpenAI Proxy Library
2//!
3//! This crate provides a high-performance proxy server that converts OpenAI-compatible
4//! API requests to Vertex AI (Anthropic Claude) format. While primarily designed as a
5//! binary application, this library exposes its core functionality for programmatic use.
6//!
7//! ## Library Usage
8//!
9//! ```rust,no_run
10//! use modelmux::{Config, create_app};
11//!
12//! #[tokio::main]
13//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
14//! // Load configuration
15//! let config = Config::load()?;
16//!
17//! // Create the application
18//! let app = create_app(config).await?;
19//!
20//! // Start server
21//! let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
22//! axum::serve(listener, app).await?;
23//!
24//! Ok(())
25//! }
26//! ```
27//!
28//! ## Modules
29//!
30//! - [`config`] - Configuration management and environment variable handling
31//! - [`provider`] - LLM backend abstraction ([`LlmProviderBackend`]); Vertex and OpenAI-compatible (stub)
32//! - [`auth`] - Request auth (GCP OAuth2 or Bearer token)
33//! - [`server`] - HTTP server setup and route handlers
34//! - [`converter`] - Format conversion between OpenAI and Anthropic formats
35//! - [`error`] - Error types and handling
36
37pub mod auth;
38pub mod config;
39pub mod converter;
40pub mod error;
41pub mod provider;
42pub mod server;
43
44// Re-export commonly used types
45pub use config::Config;
46pub use error::ProxyError;
47
48/// Creates a new ModelMux application with the given configuration.
49///
50/// This is a convenience function that sets up the full application stack
51/// including authentication, routing, and middleware.
52///
53/// # Arguments
54///
55/// * `config` - Application configuration
56///
57/// # Returns
58///
59/// Returns an Axum Router that can be served directly.
60///
61/// # Errors
62///
63/// Returns a `ProxyError` if authentication setup fails or other
64/// initialization issues occur.
65///
66/// # Examples
67///
68/// ```rust,no_run
69/// use modelmux::{Config, create_app};
70///
71/// #[tokio::main]
72/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
73/// let config = Config::load()?;
74/// let app = create_app(config).await?;
75///
76/// let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
77/// axum::serve(listener, app).await?;
78/// Ok(())
79/// }
80/// ```
81pub async fn create_app(config: Config) -> Result<axum::Router, ProxyError> {
82 use axum::Router;
83 use axum::routing::{get, post};
84 use std::sync::Arc;
85 use tower_http::cors::CorsLayer;
86 use tower_http::trace::TraceLayer;
87
88 let app_state = Arc::new(server::AppState::new(config).await?);
89
90 Ok(Router::new()
91 .route("/v1/chat/completions", post(server::chat_completions))
92 .route("/v1/models", get(server::models))
93 .route("/health", get(server::health))
94 .layer(CorsLayer::permissive())
95 .layer(TraceLayer::new_for_http())
96 .with_state(app_state))
97}