OpenAI-compatible proxy for the llama.cpp inference backend. MLX, vLLM and others coming later.
This proxy validates and normalises responses back to OpenAI shapes, as specified in openapi.with-code-samples.yml.
- llama.cpp backend: Connect to llama.cpp server instances
- Error handling: OpenAI-compatible error responses
- Streaming support: Server-Sent Events (SSE) for streaming responses
- Response Validation: All responses are validated and normalised to match OpenAI shapes.
- Advanced Parameter Support: Handles
stopsequences,max_tokens, andtemperature. - Role Mapping: Automatically maps
developerandsystemroles for compatibility.
- MLX backend: Support for Apple Silicon MLX inference
- vLLM backend: Integration with vLLM servers
- Custom backends: Easy trait for implementing your own backend
Add this to your Cargo.toml:
[dependencies]
openai-proxy = { version = "0.1", features = ["llama-backend"] }use openai_proxy::{run_proxy, LlamaBackend, BackendConfig};
use std::sync::Arc;
#[tokio::main]
async fn main() {
// Configure the backend
let config = BackendConfig {
url: "http://localhost:8080".to_string(),
model: "llama-3.1-8b".to_string(),
models: vec!["llama-3.1-8b".to_string()],
};
// Create the backend
let backend = Arc::new(LlamaBackend::new(config));
// Run the proxy server on port 8081
run_proxy(backend, 8081).await.unwrap();
}This proxy is designed to be compatible with the OpenAI API as defined in openapi.yml. It supports:
POST /v1/chat/completions- Create chat completionsGET /v1/models- List available modelsGET /health- Health check
All response types match the OpenAPI specification exactly:
CreateChatCompletionResponse- Standard chat completion responseCreateChatCompletionStreamResponse- Streaming responseErrorResponse- Error responses with proper codes
Errors are mapped to OpenAI-compatible formats:
{
"error": {
"message": "Invalid model specified",
"type": "invalid_request_error",
"param": "model",
"code": "invalid_model"
}
}To implement a custom backend, implement the InferenceBackend trait:
use async_trait::async_trait;
use futures_util::stream::BoxStream;
use openai_proxy::{
CreateChatCompletionRequest, CreateChatCompletionResponse,
CreateChatCompletionStreamResponse,
BackendResult, InferenceBackend,
};
struct MyCustomBackend;
#[async_trait]
impl InferenceBackend for MyCustomBackend {
async fn create_chat_completion(
&self,
request: CreateChatCompletionRequest,
) -> BackendResult<CreateChatCompletionResponse> {
// Your implementation
todo!()
}
async fn create_chat_completion_stream(
&self,
request: CreateChatCompletionRequest,
) -> BackendResult<BoxStream<'static, BackendResult<CreateChatCompletionStreamResponse>>> {
// Your implementation
todo!()
}
async fn list_models(&self) -> BackendResult<serde_json::Value> {
// Your implementation
todo!()
}
async fn health(&self) -> BackendResult<bool> {
Ok(true)
}
}# Build the crate
cargo build
# Run tests
cargo test
# Run with example
cargo run --example simple_proxyApache 2.0