[package]
name = "liter-llm"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
authors.workspace = true
description = "Universal LLM API client — 142+ providers, streaming, tool calling. Rust-powered, type-safe, compiled."
readme = "README.md"
keywords = ["llm", "openai", "api-client", "ai", "xberg"]
categories = ["api-bindings", "web-programming::http-client"]

[package.metadata.cargo-machete]
ignored = ["dashmap", "tower-http"]

[features]
# ---------------------------------------------------------------------------
# Transport features
# ---------------------------------------------------------------------------

# Enable the native HTTP stack (reqwest + tokio).  Disable this feature when
# compiling for WebAssembly, where the browser / Node.js fetch API is used
# instead and the tokio multi-thread runtime is unavailable.
native-http = [
    "dep:reqwest",
    # reqwest/http2 is required for `ClientBuilder::http2_prior_knowledge()` which
    # is gated behind reqwest's `http2` feature.  Enable it alongside native-http
    # so `TransportConfig::http2_prior_knowledge` can be wired through.
    "reqwest/http2",
    # dep:rustls is only satisfied on non-Windows (see target-conditional deps below).
    # Cargo silently ignores feature activations for optional deps that are absent on
    # the current target, so this entry is a no-op on Windows without causing an error.
    "dep:rustls",
    "dep:tokio",
    "dep:tokio-util",
    "dep:memchr",
    "dep:gcp_auth",
]

# WASM transport: browser / Node.js fetch API via gloo-timers.
# Mutually exclusive with `native-http`.
wasm-http = ["dep:reqwest", "dep:memchr", "dep:gloo-timers", "dep:web-time"]
# (HTTP/3 feature is declared further down — see the http3 entry under transports.)
# ---------------------------------------------------------------------------
# Observability features
# ---------------------------------------------------------------------------

# Structured tracing via the `tracing` crate.  Adds `#[instrument]` spans on
# HTTP functions and SSE parser warnings.  Can be enabled independently of the
# Tower middleware integration.
tracing = ["dep:tracing"]

# OpenTelemetry export bridge via `tracing-opentelemetry`.  Depends on `tracing`
# and re-exports `tracing_opentelemetry` so callers can compose their own
# subscriber stack without a hard dependency on the crate themselves.
# OTel is the single observability surface — no prometheus feature exists by design.
otel = ["tracing", "dep:tracing-opentelemetry", "dep:opentelemetry"]
# ---------------------------------------------------------------------------
# Middleware feature
# ---------------------------------------------------------------------------

# Tower middleware integration (LlmService, TracingLayer, FallbackLayer,
# rate_limit, budget, health, retry, circuit, hedge, cache).
tower = ["dep:tower", "dep:tower-http", "dep:futures-util", "tracing"]
# ---------------------------------------------------------------------------
# Caching feature
# ---------------------------------------------------------------------------

# Caching layer backed by opendal (memory, Redis, S3, filesystem).
# Requires the `tower` feature for the middleware stack.
opendal-cache = ["dep:opendal", "tower"]

# CEL (Common Expression Language) policy DSL for guardrails.
# Enables `CelGuardrail` in the `guardrail::cel` module.
guardrail-cel = ["dep:cel-interpreter"]
# ---------------------------------------------------------------------------
# Cloud-provider auth features
# ---------------------------------------------------------------------------

# AWS Bedrock SigV4 signing support.  Enables the `aws-sigv4` dependency and
# activates real SigV4 signing in `BedrockProvider`.  When this feature is
# disabled, `BedrockProvider` still routes `bedrock/` prefixed model names
# and strips the prefix, but sends requests unsigned (suitable for tests
# using a `base_url` override pointing to a mock server).
bedrock = ["native-http", "dep:aws-credential-types", "dep:aws-sigv4"]

# Azure AD OAuth2 credential provider (client-credentials flow).
azure-auth = ["native-http"]

# GitHub Copilot OAuth Device Flow credential provider.
copilot-auth = ["native-http"]

# Google Vertex AI OAuth2 credential provider (service-account JWT flow).
vertex-auth = ["native-http", "dep:jsonwebtoken"]

# Google Vertex AI ADC credential provider (metadata server + gcp_auth fallback).
# Back-compat alias: native-http already pulls in gcp_auth so the ADC provider
# is reachable whenever native-http is on. ADC is the recommended auth path
# for GKE / Workload Identity deployments — no service-account key file needed.
vertex-adc = ["native-http"]

# AWS STS Web Identity credential provider (EKS / IRSA token exchange).
bedrock-auth = ["native-http"]

# HTTP/3 (h3-quinn) support in reqwest. Requires the `native-http` feature.
# When enabled, the HTTP client negotiates HTTP/3 during connection establishment.
http3 = ["native-http"]
# ---------------------------------------------------------------------------
# Token counting
# ---------------------------------------------------------------------------

# Token counting via HuggingFace tokenizers.  Provides lazy-cached tokenizer
# loading and token counting for text and chat completion requests.
tokenizer = ["dep:tokenizers"]
# ---------------------------------------------------------------------------
# Composite presets
# ---------------------------------------------------------------------------

# `lite` — bare client with native HTTP, no opendal, no Tower middleware,
# no tokenizer.  Suitable for embedded usage or minimal binary size targets.
lite = ["native-http"]

# `full` — everything: native HTTP + tower + tracing + otel + bedrock +
# tokenizer + all auth providers + opendal cache.
# Default for the proxy and CLI; downstream crates use granular features.
full = [
    "native-http",
    "tower",
    "tracing",
    "otel",
    "bedrock",
    "tokenizer",
    "azure-auth",
    "copilot-auth",
    "vertex-auth",
    "vertex-adc",
    "bedrock-auth",
    "opendal-cache",
]

# etcd-backed KeyResolver implementation.
# Adds EtcdKeyResolver and EtcdKeyResolverConfig to liter_llm::tenant.
etcd-key-resolver = ["dep:etcd-client", "dep:hex", "dep:sha2"]

# Default: native HTTP only — matches `lite` without the alias.
# Keeps `cargo build` in downstream projects working without opt-in to heavy deps.
default = ["native-http"]

[dependencies]
ahash = { workspace = true }
async-trait = { workspace = true }
aws-credential-types = { version = "1", optional = true }
aws-sigv4 = { version = "1", features = ["sign-http", "http1"], optional = true }
# Unconditional: `crate::image::{encode_data_url, decode_data_url}` are
# transport-agnostic helpers used to build `data:` URIs for multimodal
# `ContentPart::ImageUrl` payloads. Previously gated behind `native-http` /
# `wasm-http`; unblocking those transports is no longer the only caller.
base64 = { workspace = true }
bytes = { workspace = true }
cel-interpreter = { version = "0.10", optional = true }
dashmap = { workspace = true }
etcd-client = { workspace = true, optional = true }
futures-core = { workspace = true }
futures-util = { workspace = true, optional = true }
gcp_auth = { workspace = true, optional = true }
gloo-timers = { version = "0.4", features = ["futures"], optional = true }
hex = { workspace = true, optional = true }
jsonwebtoken = { workspace = true, optional = true }
memchr = { workspace = true, optional = true }
opendal = { workspace = true, optional = true }
opentelemetry = { workspace = true, optional = true }
pin-project-lite = { workspace = true }
regex = "1"
rust_decimal = { workspace = true }
secrecy = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true, optional = true }
thiserror = { workspace = true }
tokenizers = { workspace = true, optional = true }
tokio = { workspace = true, features = ["time", "rt", "macros"], optional = true }
tokio-util = { workspace = true, optional = true }
toml = { workspace = true }
tower = { workspace = true, optional = true }
tower-http = { workspace = true, optional = true }
tracing = { workspace = true, optional = true }
tracing-opentelemetry = { workspace = true, optional = true }
url = { workspace = true }
web-time = { version = "1", optional = true }

# Non-Windows: use rustls + ring (avoids aws-lc-sys, the only provider bundled by default on Linux/macOS).
# The workspace reqwest base declares TLS-agnostic features; we layer the TLS provider here.
[target.'cfg(not(target_os = "windows"))'.dependencies]
reqwest = { workspace = true, optional = true, features = ["rustls-no-provider"] }
rustls = { workspace = true, optional = true }

# Windows: use SChannel via native-tls; this avoids the aws-lc-sys MSVC build failure.
# rustls is intentionally not pulled in on Windows.
[target.'cfg(target_os = "windows")'.dependencies]
reqwest = { workspace = true, optional = true, features = ["native-tls"] }

[dev-dependencies]
ctor = "1.0"
etcd-client = { workspace = true }
futures-util = { workspace = true }
jsonschema = { workspace = true }
serde_json = { workspace = true }
serial_test = { workspace = true }
tokio = { workspace = true, features = ["test-util", "macros"] }

[lints]
workspace = true
