Current section
Files
Jump to
Current section
Files
CHANGELOG.md
# Changelog
## Unreleased
## 0.2.0 - 2026-08-26
### Breaking changes
- Standalone non-secret runtime settings now come from TOML instead of
environment variables. `PORT`, `PUBLIC_URL`, `DATABASE_PATH`, `QUACKDB_URI`,
`QUACKDB_ENDPOINT`, `LLM_PROXY_RPC_SOCKET`, `LLM_PROXY_BODY_LIMIT_BYTES`,
`LLM_PROXY_PROVIDER_CONNECT_TIMEOUT_MS`, `LLM_MAX_RETRIES`,
`LLM_FALLBACKS`, and `OTEL_EXPORTER_OTLP_ENDPOINT` are no longer read.
Configure the corresponding `[server]`, `[storage]`, `[routing]`,
`[telemetry]`, provider, and model-route settings in the standalone TOML file.
- Standalone `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `OPENROUTER_API_KEYS`, and
`OPENAI_CODEX_TOKENS` bootstrapping has been removed. Seed API-key pools with
the secret `LLM_PROXY_PROVIDER_KEYS` JSON object. Provision Codex OAuth through
the admin login flow and preserve its stored token rows in backups.
- Standalone TOML is now strict and rejects unknown sections, unknown keys, and
provider credentials. Library mode remains configured through ordinary Elixir
application configuration and may source secrets however the host chooses.
- Storage upgrades add provider-token priority, API-key lifecycle state, and
content-capture policy. Existing provider tokens receive priority `0`, existing
API keys remain enabled, and trace-enabled keys retain content capture. Other
existing keys stop automatic message and cache capture after migration;
operators must apply the bundled migrations and enforce their retention policy
for content stored before this release.
### Added
- Catalog models can use latency-aware routing within each configured order tier.
The supervised node-local tracker explores cold deployments, retains bounded
fresh samples, ranks buffered calls by median attempt duration, and ranks
streams only by median time to first observable output.
- Token selection now skips accounts only while fresh provider-usage snapshots
prove exhaustion, waits for every exhausted window to reset, and persists
account- or model-scoped rate-limit cooldowns across restarts without storing
raw model IDs.
- A supervised provider-usage tracker now reports each configured OpenAI Codex
or GLM Coding Plan account separately. The optional Incant admin surface shows
live upstream windows, availability, reset times, freshness, and safe errors,
with bounded automatic refresh and manual refresh actions. Provider payloads
use strict JSONCodec boundaries, response sizes are capped, and malformed or
out-of-scope refresh results fail atomically.
- Provider-token pools support affinity or fill-first selection. Fill-first
orders healthy tokens within the existing OAuth-first/API-key-fallback
boundary by persisted non-negative priority and stable token ID.
- An optional public-model allowlist keeps HTTP discovery, setup helpers,
SafeRPC status, and request admission aligned. Standalone deployments
configure visible aliases through `catalog.public_models` in strict TOML;
library hosts use normal application configuration.
- API keys can be disabled and re-enabled without deleting their limits, usage,
or audit history. Disabled keys receive the normal invalid-key response.
- Provider API keys and OAuth tokens can use a pluggable at-rest codec with a
versioned AES-256-GCM keyring, explicit migration, verification, rotation,
and controlled plaintext rollback tasks.
- API keys can now set an in-memory concurrent-request limit with stream-safe,
process-monitored leases across in-process, ReqLLM, SafeRPC, and HTTP
generation or moderation calls.
- API keys now expose an explicit `capture_content` policy for message, trace-body,
and deterministic response-cache storage.
### Changed
- The bundled DuckDB storage dependency now requires QuackDB 0.5.20 so timestamped
Ecto migrations can roll back without overflowing migration versions.
- Content capture is disabled by default for new API keys. Usage, cost, latency,
and content-free trace metadata remain available, while message extraction,
trace-body serialization, and cache access require explicit capture consent.
- Provider fallback now has a strict attempt budget and replays only proven-safe
failures by default. Timeouts and 5xx responses require the explicit
`:allow_uncertain` compatibility policy, and visible streams are never
replayed.
### Fixed
- Active-work leases are released when their owning client process disconnects,
preventing stale activity counts from blocking drains.
### Security
- Provider-token encryption uses a keyring separate from the API master key,
creates redacted request-scoped credentials only after token selection, and
fails closed when an encrypted credential is selected without its keyring.
- Sensitive Incant fields are redacted before local rendering or remote SafeRPC
transport.
## 0.1.1 - 2026-08-01
### Fixed
- Streaming endpoints now wait for the first upstream event before committing HTTP 200, return immediate lazy-stream failures as HTTP errors, and render sanitized protocol error events when providers fail after streaming begins.
- OpenAI Codex stream failures now preserve safe upstream reasons, while trace-correlated diagnostics distinguish upstream failures from local storage errors without exposing request, query, or credential data.
- Token counters now use 64-bit database columns, and accounting exceptions are reported internally without turning a completed model stream into a client failure.
- OpenAI-compatible provider failures now return one normalized error object, forwarding structured upstream fields without duplicate `details.error` wrappers or inspected Elixir terms.
- Public HTTP and SSE errors now use protocol-native OpenAI or Anthropic envelopes across authentication, quotas, JSON parsing, draining, guardrails, moderation, routing, and provider failures; only bounded safe fields reach clients.
- Release deployment drains now work from clean release-eval VMs, advertise their bounded SafeRPC atom vocabulary, and restore request acceptance when a drain deadline expires.
- OpenAI Codex WebSockets now use a finite connection deadline with no default established-stream receive deadline, and timeout or handshake failures retain safe phase/status diagnostics.
- Named tool choices and function tool definitions now normalize across OpenAI Chat, OpenAI Responses, and Anthropic Messages routing boundaries.
- ReqLLM now uses the released Hex package at v1.18, replacing the temporary Git pin; Cowboy/Cowlib were updated to versions that resolve the newly published memory-exhaustion advisories.
### Security
- Require SafeRPC 0.1.15 or later for bounded frames, strict request validation, executable ETF rejection, and isolated listener failures.
## 0.1.0 - 2026-07-22
### Added
- In-process execution through `LLMProxy.Provider` and `LLMProxy.chat/2`.
- ReqLLM provider registration as `:llm_proxy`, including remote BEAM calls.
- Model catalog with aliases, ordered or shuffled deployments, per-deployment
timeouts, circuit breakers, retries, and fallback across providers and models.
- Direct providers for OpenAI, Anthropic, OpenRouter, OpenAI Codex, and Kimi
Code, plus an OpenAI-compatible provider helper for custom upstreams.
- Reasoning effort levels forwarded to models that support them.
- OpenAI Chat Completions (`/v1/chat/completions`) with streaming.
- Anthropic Messages (`/v1/messages`) with streaming.
- OpenAI Responses (`/v1/responses`) with streaming.
- OpenAI Moderations (`/v1/moderations`).
- Streaming heartbeats during upstream silence, bounded connection capacity,
and terminal-failure classification.
- Configurable request body limits with authentication before body parsing.
- API key management with per-key token, message, and cache quotas plus
composable budget limits.
- Provider token pools with stable user pinning and `Retry-After` cooldowns.
- Usage tracking for input, output, and cache tokens plus estimated USD cost.
- Request metadata and tags for cost attribution.
- Trace logging with request and response bodies, latency, and a feedback API.
- Guardrail hooks for request, response, and stream policy without a bundled
policy engine.
- Deterministic cache hooks for pluggable non-stream response caching.
- Embeddable storage migrations with SQLite and DuckDB (QuackDB) adapters.
- Optional Incant admin surfaces for API keys, provider tokens, traces, and
messages, plus an operations dashboard.
- OpenTelemetry instrumentation for HTTP, Ecto, and Req.
- Drain support for graceful deployments.
### Compatibility
- Requires Elixir 1.17 or later.
- Incant integration is optional and supports Incant 0.1.x.