1 unstable release
Uses new Rust 2024
| 0.1.0 | May 16, 2026 |
|---|
#1977 in Artificial intelligence
Used in 2 crates
(via yallm-server)
320KB
605 lines
yallm
Yet another LLM: a high-performance API hub that sits between clients and model providers.
The goal is to connect to any provider API and expose any downstream API surface, while keeping latency and overhead as low as possible (streaming-first, minimal allocations, strong typing where it helps).
Status
This project is alpha / work in progress.
What exists today:
- A Rust workspace with crates for an internal IR (
crates/yallm-ir) and provider adapters (crates/yallm-openai,crates/yallm-anthropic,crates/yallm-ollama). - OpenAPI-driven type generation via a proc-macro (
crates/yallm-macros) for providers that ship OpenAPI specs. - An axum server crate (
crates/yallm-server) and a CLI crate (crates/yallm-cli). - Compatibility endpoints exist and are validated with official Python SDKs.
- Real upstream provider proxying exists (OpenAI / Anthropic / Ollama), with an auto mode that falls back to deterministic mock responses when provider configuration is missing.
stream=trueis supported on all compat endpoints, including true upstream streaming in proxy mode (with cross-provider stream translation).
Project Goals
- Provider-agnostic: integrate any upstream LLM provider.
- Protocol-agnostic: support multiple downstream APIs (e.g. OpenAI-compatible, provider-native, or custom) backed by the same upstream providers.
- Performance-first: keep translation overhead tiny; preserve streaming; avoid unnecessary buffering.
- Strong types: generate/derive types from OpenAPI where possible, and convert into a shared IR to reduce protocol cross-product complexity.
Repository Layout
crates/yallm: top-level binary (starts the HTTP server)crates/yallm-cli: CLI argument parsingcrates/yallm-server: axum HTTP server (compat endpoints; real proxying + mock fallback)crates/yallm-ir: intermediate representation (IR) used for conversionscrates/yallm-openai: OpenAI types + conversions (generated from OpenAPI + hand-written mapping)crates/yallm-responses: OpenAI Responses/Conversations types + IR mapping helperscrates/yallm-storage: local JSON storage for responses/conversations historycrates/yallm-anthropic: Anthropic types + conversions (generated from vendored OpenAPI spec)crates/yallm-ollama: Ollama types + conversionscrates/yallm-macros:include_openapi!proc macro for compile-time type generationpython/yallm: thin Python wrapper that locates and execs theyallmbinary (packaging viamaturinis configured inpyproject.toml)
For agent-specific workflow notes, see AGENTS.md.
Development
Prereqs:
- Rust toolchain with edition 2024 support.
- Network access may be needed for some OpenAPI-based builds unless specs are vendored locally (details below).
Common commands:
cargo build
cargo test
cargo fmt
cargo clippy --workspace --all-targets
Run The Server (Mock Mode)
Start the server:
cargo run -p yallm -- serve --host 127.0.0.1 --port 8080
Compatibility endpoints:
- OpenAI-compatible:
POST /v1/chat/completions - OpenAI Responses-compatible:
POST /v1/responses - OpenAI Conversations-compatible:
POST /v1/conversations - Anthropic-compatible:
POST /v1/messages - Ollama-compatible:
POST /api/chat
These currently return deterministic mock responses (useful for SDK integration tests). Wiring real provider proxying is supported when configured (see below).
Responses/conversations state is stored locally so history can continue across provider switches.
Proxying To Real Providers
Provider Selection (Model Prefix)
yallm chooses the upstream provider from the model field using an openrouter/litellm-style
prefix:
openai:<model>oropenai/<model>anthropic:<model>oranthropic/<model>ollama:<model>orollama/<model>
If no prefix is present, YALLM_DEFAULT_PROVIDER is used (default: openai).
The prefix is stripped before calling upstream (e.g. anthropic:claude-3-haiku-20240307 calls
Anthropic with model claude-3-haiku-20240307).
Mode
YALLM_MODE controls behavior when provider configuration is missing:
auto(default): proxy if configured, otherwise return deterministic mock responsesproxy: always proxy; if no auth/header is supplied, the upstream decides whether to reject itmock: always mock (never calls upstream)
Configuration Layers
Config is loaded from multiple layers, highest priority first:
.yallm/secrets.toml— project secrets (gitignored).yallm/*.local.toml— per-machine overrides, applied in filename order (gitignored).yallm/config.toml— committed project config~/.yallm/config.toml— user defaults- OS environment variables
.env— only fills keys absent from OS env (does not override)
Each TOML file uses an [env] table:
[env]
ANTHROPIC_API_KEY = "sk-ant-..."
YALLM_DEFAULT_PROVIDER = "anthropic"
Provider Environment Variables
OpenAI:
OPENAI_API_KEY(compatibility sugar forAuthorization: Bearer <key>)OPENAI_BASE_URL(defaulthttps://api.openai.com)YALLM_OPENAI_HEADERS(optional JSON object of additional upstream headers)
Anthropic:
ANTHROPIC_API_KEY(compatibility sugar forx-api-key: <key>)ANTHROPIC_AUTH_TOKEN(compatibility sugar forAuthorization: Bearer <token>)ANTHROPIC_BASE_URL(defaulthttps://api.anthropic.com)ANTHROPIC_VERSION(default2023-06-01)YALLM_ANTHROPIC_HEADERS(optional JSON object of additional upstream headers)
Ollama:
OLLAMA_BASE_URL(defaulthttp://localhost:11434)YALLM_OLLAMA_HEADERS(optional JSON object of additional upstream headers)
YALLM_*_HEADERS values may use os.environ/VAR or ${VAR} references, including interpolation
such as "Authorization": "Bearer ${UPSTREAM_TOKEN}".
Request header forwarding:
YALLM_FORWARD_HEADERScontrols which downstream request headers may be forwarded upstream. Defaults to common provider headers:authorization,x-api-key,api-key,openai-organization,openai-project,anthropic-version,anthropic-beta. Set it tononeto disable request header forwarding.- Header precedence is: provider env/default headers, then model-route headers, then allowlisted request
headers. If a higher-priority source supplies an auth header (
authorization,x-api-key, orapi-key), lower-priority auth headers are dropped.
Local storage:
YALLM_DB_URL(optional): persistent database URL for responses, conversations, and dashboard monitoring events. Defaults tosqlite://<cache-dir>/yallm/storage.sqlite3.- Supported URL schemes are currently
sqlite://,sqlite::memory:,file://, and bare file paths. Other database URL schemes fail explicitly until a backend is added inyallm-storage. YALLM_STORAGE_PATHis a deprecated compatibility path for the old local JSON store.
LiteLLM Config Compatibility
Point yallm at a LiteLLM config.yaml with --litellm-config <path> or
YALLM_LITELLM_CONFIG=<path>. The CLI flag wins when both are set.
Each model alias is reachable via every supported protocol — yallm converts
between OpenAI / Anthropic / Ollama formats on the fly. An alias whose upstream
is openai/gpt-4o can be called from /v1/chat/completions, /v1/messages,
or /api/chat. GET /v1/models therefore lists the same alias set under every
?interface= filter.
yallm_params (preferred) vs litellm_params (compatibility)
litellm_params exists for drop-in compatibility with existing LiteLLM
config files. New configs should use yallm_params, which makes the provider
explicit instead of prefix-encoding it in the model string. When both blocks
appear on the same entry, yallm_params wins.
model_list:
- model_name: gpt-alias
yallm_params: # preferred
provider: openai # one of: openai | anthropic | ollama
model: gpt-4o
api_base: https://openai-compatible.example/v1
api_key: os.environ/OPENAI_API_KEY
headers:
OpenAI-Organization: ${OPENAI_ORG_ID}
forward_headers:
- authorization
- x-request-id
- model_name: claude-alias # legacy LiteLLM-style entry still works
litellm_params:
model: anthropic/claude-3-haiku-20240307
api_key: os.environ/ANTHROPIC_API_KEY
headers:
anthropic-beta: prompt-caching-2024-07-31
Supported litellm_params v1 fields: model_name and
litellm_params.model/api_base/api_key/api_version/custom_llm_provider/headers/forward_headers for
OpenAI-compatible, Anthropic, and Ollama upstreams. Exact aliases take priority
over prefix/default-provider routing. Advanced LiteLLM router features,
fallback rules, budgets, wildcard model groups, and Azure OpenAI routing are
not implemented.
Use env references for keys instead of committing secrets — both
os.environ/VAR and ${VAR} syntaxes are accepted. Header values additionally support interpolation,
for example Authorization: Bearer ${UPSTREAM_TOKEN}.
Logging (Fluentd-Friendly JSON)
yallm emits JSON logs to stdout using tracing. The server logs:
- inbound HTTP requests (
event=http.in) - outbound HTTP responses (
event=http.out) - provider requests/responses (
event=provider.out/event=provider.in) - conversion stages (
event=convert.*)
Redaction/truncation controls:
YALLM_LOG_REDACT_SECRETS=1(default): redact auth headers and common secret JSON keysYALLM_LOG_BODY_MAX_BYTES=0(default): log full bodies; set to truncate and still logbody_len
OpenAPI Type Generation
Provider crates use yallm_macros::include_openapi! { ... } to generate Rust types from OpenAPI
schemas at compile time.
Notes:
- The macro fetches and caches specs. If your default cache directory is not writable, set
YALLM_CACHE_DIRto a writable path. crates/yallm-anthropic/openapi.ymlis vendored in-repo so it can build offline. Abuild.rsexists to refresh the spec, but is opt-in (setYALLM_UPDATE_ANTHROPIC_OPENAPI=1).crates/yallm-openaican fetch its OpenAPI spec at build time if a local copy is not present. If you need fully offline builds, place a local spec file in the crate (see theinclude_openapi!config incrates/yallm-openai/src/lib.rs).
Deterministic Offline Build Recipe
To make builds reproducible and offline-friendly:
- Prefetch dependencies once:
cargo fetch --locked - Keep vendored specs pinned (do not refresh Anthropic during normal builds):
export YALLM_UPDATE_ANTHROPIC_OPENAPI=0 - Build/test in offline mode:
export CARGO_NET_OFFLINE=true cargo check --workspace --locked cargo test --workspace --locked - (Optional guard) verify vendored Anthropic spec was not mutated:
git diff --exit-code -- crates/yallm-anthropic/openapi.yml
Roadmap (High Level)
- Expand streaming fidelity (tool-call deltas, finer-grained usage/finish metadata, and broader protocol edge-case coverage).
- Add a provider/protocol registry to make “any provider” x “any API surface” composable.
- Add real-world docs and examples (curl requests, streaming examples, tool-calls).
- Expand CI coverage (e.g., matrix builds and additional checks).
License
MIT. See LICENSE.
Dependencies
~18–47MB
~834K SLoC