mod handlers;
mod types;
use axum::Router;
use std::sync::Arc;
use tower_http::cors::CorsLayer;
use crate::chain::LLMRegistry;
use handlers::handle_chat;
pub use types::{ChatRequest, ChatResponse, Message};
pub struct Server {
llms: Arc<LLMRegistry>,
pub auth_key: Option<String>,
}
#[derive(Clone)]
struct ServerState {
llms: Arc<LLMRegistry>,
auth_key: Option<String>,
}
impl Server {
pub fn new(llms: LLMRegistry) -> Self {
Self {
llms: Arc::new(llms),
auth_key: None,
}
}
pub async fn run(self, addr: &str) -> Result<(), crate::error::LLMError> {
let app = Router::new()
.route("/v1/chat/completions", axum::routing::post(handle_chat))
.layer(CorsLayer::permissive())
.with_state(ServerState {
llms: self.llms,
auth_key: self.auth_key,
});
let listener = tokio::net::TcpListener::bind(addr)
.await
.map_err(|e| crate::error::LLMError::InvalidRequest(e.to_string()))?;
axum::serve(listener, app)
.await
.map_err(|e| crate::error::LLMError::InvalidRequest(e.to_string()))?;
Ok(())
}
pub fn with_auth_key(mut self, key: impl Into<String>) -> Self {
self.auth_key = Some(key.into());
self
}
}