The feature matrix

In one line
Thirty-one opt-in features: eight providers, five provider-local GPU features, twelve plugins, six services
You need
At least one provider-* feature; the build stops without one
Read this if
You are choosing a feature list, or tracing which crate a feature pulls in

default = []. Every feature below is off until you enable it. The source of truth is the [features] table in Cargo.toml.

The provider gate

A build with none of the eight provider features stops at a compile_error! in src/lib.rs:

CUCA requires one provider-* feature; enable the adapter for the backend you use.

The gate is a #[cfg(not(any(...)))] over provider-openai, provider-anthropic, provider-deepseek, provider-gemini, provider-llamacpp, provider-vllm, provider-lmstudio and provider-local. The five GPU features are not providers and do not satisfy it. CI asserts that cargo check --no-default-features fails.

Provider features

Eight features: seven HTTP adapters and one in-process engine. Each dep: entry is an optional dependency the feature turns on.

FeatureEnables
provider-openaidep:reqwest, dep:tokio-stream, reqwest/rustls
provider-anthropicdep:reqwest, dep:tokio-stream, dep:sha2, dep:getrandom, dep:base64, reqwest/rustls
provider-geminidep:reqwest, dep:tokio-stream, reqwest/rustls
provider-deepseekdep:reqwest, dep:tokio-stream, reqwest/rustls
provider-llamacppdep:reqwest, dep:tokio-stream, reqwest/rustls
provider-vllmdep:reqwest, dep:tokio-stream, reqwest/rustls
provider-lmstudiodep:reqwest, dep:tokio-stream, reqwest/rustls
provider-localdep:candle-core, dep:candle-nn, dep:half, dep:minijinja, dep:minijinja-contrib, dep:reqwest, dep:sha2, dep:tokio, dep:unicode-general-category, reqwest/rustls

provider-local does not use tokio-stream: its stream is a plain mpsc receiver. It uses reqwest only for the one-time model download.

Local GPU features

Five features extend provider-local. None is a provider.

FeatureEnables
provider-local-gpuprovider-local, dep:burn
provider-local-vulkanprovider-local-gpu, burn/vulkan
provider-local-metalprovider-local-gpu, burn/metal
provider-local-cudaprovider-local-gpu, burn/cuda
provider-local-rocmprovider-local-gpu, burn/rocm
  • provider-local-gpu is the shared GPU engine. It selects no backend by itself; each backend feature enables it.
  • provider-local alone runs the model on the CPU.
  • LocalDevice and GpuAdapter exist in every provider-local build. Selecting a backend whose feature is off makes LocalModel::load fail with CucaError::Config.
  • provider-local-cuda and provider-local-rocm download a prebuilt LLVM on the first build. ROCm builds on Linux only.

Plugin features

Twelve features. Each plugin implements CucaPlugin and runs on the request pipeline.

FeatureEnables
plugin-mcpdep:rmcp, dep:tokio
plugin-sandboxdep:wasmtime, dep:base64, wasmtime/wat
plugin-memorydep:tiktoken-rs
plugin-guardrailsdep:jsonschema, dep:tracing
plugin-subagentdep:tokio
plugin-hitldep:tokio
plugin-web-searchdep:reqwest, dep:tokio, reqwest/rustls
plugin-skillsnothing
plugin-telemetrydep:opentelemetry, dep:opentelemetry_sdk, dep:tracing
plugin-session-logdep:postcard
plugin-costdep:tiktoken-rs
plugin-redactiondep:tracing

No plugin feature enables another plugin feature, and none names a service: the tier is flat.

Service features

Six features. A service is driven by direct method calls and never implements CucaPlugin.

FeatureEnables
service-entity-extractionplugin-memory
service-speculativedep:tokio, dep:tokio-stream
service-replayplugin-session-log
service-prompt-cachedep:sha2, dep:postcard
service-rate-limitdep:tokio
service-vector-storeplugin-memory, dep:wide

Feature edges

Three hard edges, all service to plugin:

  • service-entity-extraction = ["plugin-memory"]
  • service-replay = ["plugin-session-log"]
  • service-vector-store = ["plugin-memory", "dep:wide"]

One optional edge, not a Cargo feature: ModelOrchestrator::with_session_store exists only when service-speculative and plugin-session-log are both enabled.

service-prompt-cache and service-rate-limit declare no plugin dependency. A plugin never depends on, or names, a service.

Unconditional dependencies

Five crates compile in every build. They carry the public wire types, the SSE parser and the response stream contract.

CrateVersionFeatures
bytes1default
futures-core0.3default
memchr2default
serde1derive
serde_json1default

Optional dependencies

CrateVersionDeclared featuresOwned by
reqwest0.13json, stream, form; no defaultsthe eight provider-*, plugin-web-search
tokio1rt, time, macros, sync, process; no defaultsprovider-local, plugin-mcp, plugin-subagent, plugin-hitl, plugin-web-search, service-speculative, service-rate-limit
tokio-stream0.1defaultthe seven HTTP provider-*, service-speculative
sha20.11defaultprovider-anthropic, provider-local, service-prompt-cache
getrandom0.4defaultprovider-anthropic
base640.23noneprovider-anthropic, plugin-sandbox
rmcp3client, transport-child-process, transport-streamable-http-client-reqwestplugin-mcp
wasmtime48default, plus watplugin-sandbox
tiktoken-rs0.12defaultplugin-memory, plugin-cost
jsonschema0.52no defaultsplugin-guardrails
opentelemetry0.32defaultplugin-telemetry
opentelemetry_sdk0.32metrics, testingplugin-telemetry
tracing0.1defaultplugin-guardrails, plugin-telemetry, plugin-redaction
postcard1use-std; no defaultsplugin-session-log, service-prompt-cache
wide1.7defaultservice-vector-store
candle-core0.11.0no defaultsprovider-local
candle-nn0.11.0no defaultsprovider-local
half2defaultprovider-local
minijinja2.24loaderprovider-local
minijinja-contrib2.24pycompatprovider-local
unicode-general-category1defaultprovider-local (the byte-level BPE pre-tokenizers)
burn0.22std, fusion, autotune; no defaultsprovider-local-gpu (backends burn/vulkan, burn/metal, burn/cuda, burn/rocm)

Why some defaults are off

  • reqwest has no defaults, so TLS arrives only through the reqwest/rustls entry that every provider-* feature and plugin-web-search carries.
  • jsonschema has no defaults because guardrails compiles inline schemas only and needs no $ref retrieval.
  • postcard has no defaults because its default heapless-cas feature pulls in heapless, which the crate never uses. use-std supplies the std buffer and COBS helpers.
  • burn has no defaults because they enable the optimizer and autodiff, which inference never uses.

C compilers and downloads

  • candle-core hard-depends on tokenizers[onig], so provider-local compiles C through onig_sys and needs a C compiler.
  • The Vulkan and Metal backends are Rust (wgpu: SPIR-V, MSL). Every GPU feature still compiles C, because CubeCL's runtime pulls an embedded store (turso) that builds C through cc.
  • On Windows, a dependency's build script runs the SDK resource compiler (rc.exe; windres on the GNU target) for the GPU features.
  • provider-local-cuda and provider-local-rocm pull CubeCL's LLVM backend. Its build script, tracel-llvm-bundler, downloads a prebuilt LLVM on the first build (network needed once, then cached) and links it statically.
  • docs.rs builds have no network, so the [package.metadata.docs.rs] feature list names every feature except those two.

Feature-conditional modules

ModuleGate
exportplugin-memory or service-prompt-cache
cost_otelplugin-cost and plugin-telemetry

Every other public module compiles unconditionally: types, error, request, session, sse, plugin, plugins, services, client. The plugins and services modules are always present. Their submodules are individually gated, so each is empty when none of its features is on. The provider module is pub(crate).

Crate metadata

FieldValue
Package namecuca
Version0.5.2
Edition2024
rust-version1.98
Pinned toolchain1.98.0, from rust-toolchain.toml
LicenseApache-2.0
[lib] doctestfalse
Binary targetsnone

doctest = false because the doctest pass does a plain library build that the provider gate rejects, and the crate has no doctests.

Example targets

Twenty-three examples. All but local_model require provider-llamacpp. Run one with cargo run --example <name> --features <list>.

ExampleRequired features
llamacpp_gemma, stream_all_blocks, custom_pluginprovider-llamacpp
local_modelprovider-local
costprovider-llamacpp, plugin-cost
cost_otelprovider-llamacpp, plugin-cost, plugin-telemetry
entity_extractionprovider-llamacpp, service-entity-extraction
guardrailsprovider-llamacpp, plugin-guardrails
hitlprovider-llamacpp, plugin-hitl
mcpprovider-llamacpp, plugin-mcp
memoryprovider-llamacpp, plugin-memory
prompt_cacheprovider-llamacpp, service-prompt-cache
rate_limitprovider-llamacpp, service-rate-limit
redactionprovider-llamacpp, plugin-redaction
replayprovider-llamacpp, service-replay
sandboxprovider-llamacpp, plugin-sandbox
session_logprovider-llamacpp, plugin-session-log
skillsprovider-llamacpp, plugin-skills
speculativeprovider-llamacpp, service-speculative
subagentprovider-llamacpp, plugin-subagent
telemetryprovider-llamacpp, plugin-telemetry
vector_storeprovider-llamacpp, service-vector-store
web_searchprovider-llamacpp, plugin-web-search

Examples live in examples/<name>.rs.

Bench target

benches/vector_store.rs is a Divan benchmark with harness = false. It requires provider-openai and service-vector-store. No CI job runs it.

Feature combinations CI verifies

JobFeature list
clippy, test--no-default-features --features provider-openai, and --no-default-features --features $ALL_NO_LLVM
no_provider--no-default-features, asserted to fail
doc--no-default-features --features $ALL_NO_LLVM
local_gpu_llvm--all-targets --no-default-features --features provider-local-cuda,provider-local-rocm, cargo check on Ubuntu; the only job that downloads the LLVM bundle
plugin_solo--no-default-features --features provider-openai,<plugin>, once per plugin feature (twelve)
service_solo--no-default-features --features provider-openai,<service>, once per service feature (six)
plugin_layeringgreps asserting no file under src/plugins/ names a service- feature, a crate::services path, or a plugins:: path for prompt_cache, entity_extraction, replay or rate_limit

ALL_NO_LLVM is a top-level env entry in .github/workflows/ci.yml, the same list as the docs.rs feature set: every feature except provider-local-cuda and provider-local-rocm. The run steps expand it as $ALL_NO_LLVM.

↑↓ to navigate ↵ to open esc to close