- In one line
- Eight
provider-*features, each owning onedispatch_*method and oneProviderEndpointvariant - You need
- At least one
provider-*feature enabled; the crate does not compile without one - Read this if
- You need a base URL, an auth header, a route, or the exact behavior one adapter does not share with the others
Compare the adapters
| Feature | ProviderEndpoint | Default base URL | Auth header |
|---|---|---|---|
provider-openai | OpenAi | https://api.openai.com/v1 | Authorization: Bearer, when a key is set |
provider-anthropic | Anthropic | https://api.anthropic.com/v1 | x-api-key, or Authorization: Bearer for a bearer token |
provider-gemini | GoogleGemini | https://generativelanguage.googleapis.com | x-goog-api-key, required |
provider-deepseek | DeepSeek | https://api.deepseek.com/v1 | Authorization: Bearer (native), x-api-key (bridge) |
provider-llamacpp | LlamaCpp | http://127.0.0.1:8080 | Authorization: Bearer, when a key is set |
provider-vllm | Vllm | http://127.0.0.1:8000/v1 | Authorization: Bearer, when a key is set |
provider-lmstudio | LmStudio | http://127.0.0.1:1234/v1 | Authorization: Bearer, when a key is set |
provider-local | Local | none, runs in your process | none |
- The default base URL applies when the client's base URL is empty. Set another with
CucaClientBuilder::with_base_url. - Each provider page lists the route, the request and stream translation, thinking, errors and limits under the same headings.
- Every HTTP feature enables
reqwestwith itsrustlsbackend andtokio-stream.provider-anthropicalso enablessha2,getrandomandbase64. - The feature matrix maps every feature to its dependencies.
Wire formats
The seven HTTP adapters speak four wire formats and share two translation modules.
| Wire format | Adapters | Stream ends at |
|---|---|---|
OpenAI-compatible /chat/completions | OpenAI, vLLM, LM Studio, DeepSeek native, llama.cpp chat | data: [DONE] |
| Anthropic Messages | Anthropic, DeepSeek bridge | message_stop event |
Gemini streamGenerateContent | Gemini | the end of the byte stream |
llama.cpp native /completion | llama.cpp with LlamaRoute::Completion | the end of the byte stream |
src/provider/openai_compat.rsholds the OpenAI-compatible translation, documented on the OpenAI page.src/provider/anthropic.rsholds the Anthropic translation, documented on the Anthropic page.- Gemini and the llama.cpp native route each have their own translator.
The in-process adapter
provider-local runs a GGUF language model inside your process and exposes no HTTP endpoint. It has no base URL, auth header or route.
ProviderEndpoint::Localselects it, andCucaClientBuilder::with_local_modelattaches the model.buildfails when the selected provider isLocaland no model is attached.- The CPU is the default device.
provider-local-vulkan,provider-local-metal,provider-local-cudaandprovider-local-rocmadd a GPU engine thatLocalModelConfig::deviceselects. - It does not use
tokio-stream. It usesreqwestonly for the one-time model download. - The engine is pure Rust. The
candledependency tree builds one C crate,onig_sys.
See Local (in-process) for configuration and behavior, and Local models and formats for the supported architectures and presets.
Dispatch
There is no provider trait. Each adapter module contributes an inherent impl CucaClient block with one method:
pub(crate) async fn dispatch_<provider>(
&self,
req: UnifiedRequest,
) -> Result<ProviderDispatch, CucaError>
CucaClient::generate_stream sets request.provider to the client's selected provider, runs the on_request hooks, then selects an adapter with a match on self.selected_provider. Each arm is gated on its feature. A mirrored #[cfg(not(feature = ...))] arm returns CucaError::ProviderNotEnabled with the missing flag name.
Custom endpoints
ProviderEndpoint has nine variants: the eight above and Custom(String). Custom has no feature and no adapter. Dispatching it returns CucaError::Config:
configuration error: custom endpoints require a registered adapter
ProviderEndpoint::default()isOpenAi.UnifiedRequest::newsets the request's provider toCustom(String::new()), andgenerate_streamoverwrites it with the client's provider before any hook runs.
Environment variables
None of the seven HTTP adapters reads an environment variable. Base URLs, API keys and bearer tokens reach them only through CucaClientBuilder. The CUCA_* variables that belong to the examples and the test harness are listed in Environment variables.
provider-local reads two variables as fallbacks:
CUCA_CACHE_DIR, then the platform's cache variables, whenLocalModelConfig::cache_dirisNone.HF_TOKENwhenLocalModelConfig::hf_tokenisNone.
Setting the config fields keeps it from reading either.
Related pages
- Unified request explains the request every adapter translates.
- Use another OpenAI-compatible server shows how to point an adapter at a server not listed here.