allama
Low-level, provider-agnostic LLM abstractions for Rust.
allama is a low-level crate for code that wants one interface for LLM APIs
(chat, embeddings, and decision models) while leaving HTTP transport, request translation,
and response parsing to provider implementations.
Use it when you want to:
- write application code against one provider-neutral contract
- implement a provider adapter on top of shared request and response types
- normalize streaming, tool calls, usage, and errors across providers
- move conversations between providers without leaking opaque state
- produce embedding vectors from multiple providers with a single trait
- ask decision models typed questions (yes/no, choice, score) and read
probabilities, untyped or through
#[derive(Decision)]
allama is intentionally not a provider client and not an agent framework.
You May Be Looking For
- API docs: https://docs.rs/allama
ChatProvider: https://docs.rs/allama/latest/allama/trait.ChatProvider.htmlEmbeddingProvider: https://docs.rs/allama/latest/allama/trait.EmbeddingProvider.htmlDecisionProvider: https://docs.rs/allama/latest/allama/trait.DecisionProvider.html- chat example:
chat.rs - embedding example:
embedding.rs - decision example:
decision.rs - streaming example:
stream.rs - provider implementation example:
provider_impl.rs
Quick start
Pick the provider and model at runtime from one string, a model address
such as openai:gpt-5.5, with
allama-providers:
[]
= "0.1"
= "0.1"
= "1"
= { = "1", = ["macros", "rt-multi-thread"] }
use *;
async
Streaming, conversations, and what to settle before production (the
120 s Retry-After ceiling of the default retries among them) are in the
workspace README.
The terms the docs use are defined in the
glossary.
Without credentials
This example uses the built-in mock provider, so it runs without credentials.
[]
= { = "0.1", = ["mock"] }
= "1"
= { = "1", = ["macros", "rt-multi-thread"] }
use MockProvider;
use *;
async
From the workspace root:
MockProvider replays a script and returns an error once the script runs
out. For tests that send many requests, such as HTTP handler tests, use
TestProvider, which answers every request. The
allama::mock docs explain
which mock to pick and when scripted errors surface.
Core concepts
| Concept | Types |
|---|---|
| Requests | ChatRequest, Message, ContentPart (Text, Image, File), MediaSource (Url, Base64, ProviderFile), SystemPrompt, ToolDefinition, ToolChoice, ResponseFormat, ReasoningConfig, PromptCache |
| Responses | ChatResponse, ContentBlock (Text, Image, ToolCall, Reasoning, Refusal, ProviderToolCall, ProviderToolResult, Other), FinishReason, Usage, Warning |
| Decisions | DecisionRequest, DecisionResponse, DecisionLimits; in decision: DecisionInput, Question (yes_no, choice, score), Answer; typed: Decision, ChoiceSet, Scale, Choice, Score, DecisionProviderExt::decide_as |
| Streaming | StreamEvent, ChatStreamExt::{next_event, collect_response, with_collector}, CollectedEvent; in chat::stream: StreamCollector, StreamTranscript, until_committed |
| Provider escape hatches | ProviderOptions / RequestOptions (typed or JSON request options), ProviderData (namespaced provider state on blocks, messages, responses) |
| Policy | UnsupportedPolicy (warn or fail on unsupported hints) |
| Provider authoring | adapter::{chat, embedding, decision, schema} (prepare, preflight, WireSupport, the JSON Schema passes), adapter::Degradations |
| Errors | Error (RateLimited, QuotaExhausted, ContextLengthExceeded, Stream { kind }, …) with retry_after, request_id, is_retryable |
| Composition | wrappers::{RetryingProvider, FallbackProvider, TimeoutProvider, MapModelProvider, MapRequestProvider, RecordingProvider, TracingProvider}, extract::ExtractExt, typed lookup through wrappers (ProviderIdentityExt::downcast_ref) |
| Persistence | history::History (versioned envelope), history::retain_portable_content for client-held history; requests and responses are Serialize/Deserialize |
Features
The only default feature is warning-events. A library that depends on
allama turns default features off, so the application alone decides.
| Feature | What it enables |
|---|---|
warning-events (default) |
every warning a call reports is also a tracing event (targets allama::warning::<kind>, deduplicated by code), and retries and failovers are allama::retry and allama::fallback events |
schema |
ToolDefinition::from_schema::<T>(), ResponseFormat::from_schema::<T>() and allama::adapter::schema::schema_for via schemars, re-exported as allama::schemars; field paths in ToolArgumentsError via serde_path_to_error |
derive |
#[derive(Decision, ChoiceSet, Scale)] for typed decisions (allama-derive) |
extract |
structured extraction (ExtractExt, Extractor); implies schema |
mock |
test doubles: MockProvider, MockStreamingProvider, MockEmbeddingProvider, MockDecisionProvider, FunctionProvider, TestProvider |
tracing |
OpenTelemetry GenAI spans via wrappers::TracingProvider |
Implementing A Provider
Implement ProviderIdentity, then any of ChatProvider,
EmbeddingProvider, and DecisionProvider. A provider:
- reads its options with
request.resolve_option::<YourOptions>(), - reports unsupported fields through
Degradations(semantic fields fail, hints warn or fail underUnsupportedPolicy::Error), - stores replay state in
ProviderDataunder its own namespace and replays only that namespace, whichProviderIdentity::reads_namespaceanswerstruefor, - names itself with
ProviderIdentity::provider_nameand answerschat_capability/embedding_capability/decision_capability(CapabilitySupport::Unknownwhen it does not know); both are required, - exposes itself through
ProviderIdentity::downcast_any(expose), so callers can reach it behind wrappers withdowncast_ref, - normalizes usage to the contract in
Usage(input includes cache, output includes reasoning) and stampsChatResponse::provider.
A wrapper is transparent: it forwards the name, the namespaces it reads,
downcast_any, capability answers, limits, and validation to the provider
it wraps, and passes its responses, stream events and errors through
unchanged. The allama::wrappers::forward_* macros forward every
question, so a wrapper writes only its operations, and
allama_conformance::assert_wrapper checks it. Middleware (an
async request hook, response and stream observation) is a wrapper; the
middleware example
is the recipe.
Providers without native streaming can return SingleResponseStream.
allama-conformance provides fixture helpers and shared behavioral
contracts. The annotated guide is
provider_impl.rs.
Status
- Pre-1.0: a minor release (0.x to 0.x+1) may break the API; a patch release does not.
- Every
allama-*crate shares one version and is released with the others.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.