Claude Code's /model picker showed fake 'Claude Sonnet/Opus/Haiku' because /v1/models returned the static Anthropic catalog and the launch command did not enable discovery. With the Auto Router on, /v1/models now advertises the real backend models (autorouter tier targets + managed backend catalogs + model_list), and a model picked from the picker routes straight to its backend (explicit pick wins over tier signals). claude-* alias traffic still flows through the configured tiers.
- /v1/models: real models when router enabled; static Anthropic catalog fallback otherwise
- explicit-pick deferral in /v1/messages and /v1/chat/completions (AppState::resolve_explicit_pick)
- CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=true in the Auto Router copy-command and the README/CLI launch instructions
- tests: unit (push_model_row, RouterConfig::active_tiers) + integration (explicit_pick beats think tier)
Co-Authored-By: Claude <noreply@anthropic.com>
mlx-v is a Rust candle-backed vision-language inference toolkit whose
`vlm serve` exposes an OpenAI-compatible endpoint, defaulting to
localhost:8080. Registering it means the proxy can front a local VLM the same
way it fronts LM Studio or Ollama, which in practice means Anthropic
/v1/messages against a local candle model.
Capabilities differ from the neighbouring local backends in two ways worth
naming: embeddings is false (mlx-v has no /v1/embeddings route, unlike
lm_studio and ollama which advertise one), and tool_choice is false (mlx-v
honors "auto" and "none" but rejects "required" and named functions, having
no constrained decoding).
No litellm_snapshot change: mlx-v is not in LiteLLM, which is what the
LEGACY_ONLY_* arrays are for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Auth default is now loopback-open (not reject-all). With no
PROXY_API_KEYS, no PROXY_OPEN_RELAY, no virtual keys and no OIDC,
loopback TCP peers are accepted and LAN/remote peers get 401. The
decision uses the real TCP peer (ConnectInfo via
into_make_service_with_connect_info), not the spoofable
X-Forwarded-For. effective_auth_mode() (keys/open_relay/loopback_only)
+ proxy_key_count are surfaced on GET /admin/api/status; the admin UI
shows a warning banner when no key is set.
- Add --port/-p CLI flag that sets LISTEN_PORT for the run. Stripped
before any run/providers subcommand so flags meant for the launched
tool survive; pure scan is unit-tested.
- Startup port handling: the run subcommand pre-checks the listen port
and fails fast with a hint when in use; wait_for_port readiness timeout
10s -> 30s; listener bind failures (proxy + admin) now print an
actionable message and exit(1) instead of panicking.
- POST /v1/chat/completions no longer 400s on a missing max_tokens for
OpenAI-compatible backends. The internal placeholder is stripped via a
new OMIT_MAX_TOKENS_MARKER so the backend applies its own default
(e.g. LM Studio's 8192); the marker never leaks upstream. Explicit
max_tokens is still forwarded verbatim. Anthropic backends unchanged.
- Tier router logs the selected tier at info (tier/backend/model)
instead of routing silently.
- Admin UI modal no longer dismisses when a text-selection drag starts
inside the card (dismiss only on a press that begins on the backdrop).
Co-Authored-By: Claude <noreply@anthropic.com>
Admin/browser:
- Enable admin UI on bare (zero-arg) launch; auto-open default browser
(main_helpers::bootstrap::admin_enabled / is_default_launch, browser.rs).
- Guard Docker (docker-entrypoint.sh) and systemd (packaging/anyllm-proxy.service)
so headless server installs keep admin opt-in (DISABLE_ADMIN default off).
Claude Code tier router fixes (from code review):
- put.rs: validate only *enabled* tiers, and accept statically-configured
(all_backends) targets via new SharedState.static_backends, not just managed.
- openai_signals: drop historical reasoning_content check so a plain follow-up
in a reasoning conversation isn't misrouted to the Think tier.
- resolve_router_tier: warn! on fail-open when an active tier's backend is
unknown instead of silently bypassing the router.
Tests: static-config backend acceptance; existing router coverage still green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Split config.rs into config/{mod,delete,get,put}.rs
- Split routes_api.rs into routes_api/{mod,helpers,providers,routes}.rs
- Split passthrough/handlers.rs into handlers/{mod,errors,generic,messages}.rs
- Split streaming.rs into streaming/{mod,handler,helpers}.rs
- Split main_helpers/async_main/admin.rs into admin/{mod,config,tasks}.rs
- Minor cleanups in chat_completions backends, token_counting, tests
- Add docs/TEST_PARITY_LITELLM.md
Co-Authored-By: Claude <noreply@anthropic.com>
Add [Unreleased] entries for RTK tool-output compression and the opt-in prompt
optimizer, and document their RTK_* / OPTIMIZER_* / MODEL_* env vars and config
keys in docs/ENV.md and docs/CONFIG.md. Also records the already-committed
Bedrock native-route model-allowlist fix and the model-discovery URL fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds opt-in client-credential forwarding for Anthropic passthrough
(single-key/BYOK deployments), plus fixes found in review:
- Startup safeguard now shares one check (server/middleware/auth.rs)
with the live admin PUT /admin/api/config path, closing a bypass
where PROXY_OPEN_RELAY=true alongside 2+ PROXY_API_KEYS entries
slipped past the old startup-only check.
- x-goog-api-key is now recognized as a forwardable credential
(renamed to x-api-key upstream, since Anthropic doesn't understand
that header name), matching validate_auth's precedence.
- Managed (admin-API) backends no longer carry a dead
forward_client_auth field that could never take effect.
- ClientAuthPath forwarding decisions are now double-checked against
live VirtualKeyContext/JwtClaims presence, not just the enum, to
fail closed if the two ever desync.
- Moved from a per-backend BackendConfig field to a global
RuntimeConfig field (like anthropic_thinking_repair), making it
live-toggleable from the admin UI with no restart, and uniform
across every Anthropic-kind backend in a multi-backend deployment.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Tool-call guardrails (lsp_first/quiet_command/write_payload_cap nudges,
fingerprint dedup) for local-LLM tool loops. Configurable via YAML
tool_execution.guardrails, FORGE_TOOL_CALL_POLICY env fallback, or the
admin UI (live, no restart).
- Anthropic thinking-block record/repair (ANTHROPIC_THINKING_REPAIR):
records ground truth off the real API and repairs client-corrupted
thinking/redacted_thinking blocks in replayed conversations.
- Bidirectional thinking_blocks (signature/redacted state) round-trip
through the OpenAI-compat wire format for LiteLLM-style clients.
- Review fixes: guardrail-mode divergence between streaming/non-streaming
paths, cross-backend/tenant cache-namespace collision, client-controlled
integer overflow in thinking budget_tokens, dropped reasoning_content and
citations on repair/translation paths, a fail-closed race under cache
eviction, plus dedup/simplification cleanup and doc corrections.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Large admin-ui refactor (Performative component system, sidebar nav,
provider/route tabs) plus backend module restructuring.
Admin UI contract fixes (this session):
- Fix Models page crash: useBackends unwraps {backends:[...]}; align
ModelEntry to {model_name, deployments} and ModelsResponse.strategy;
fix add-model body to {model_name, actual_model, backend_name}.
- Fix Backends/Providers health rendering: source per-backend status and
latency from the uptime endpoint (health_checks); narrow Backend type to
the real get_backends shape.
- Route + sidebar-link the previously-unrouted Backends tab.
Verified: cargo test (exit 0), clippy -D warnings (exit 0), fmt --check,
admin-ui tsc + vite build all green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New providers: assemblyai, baidu, blackboxai, brave, cartesia, deepgram,
elevenlabs, exa, iflytek, lmsys, playht, pollinations, serper, siliconflow,
stability, tavily. Registered in mod.rs and registry.rs.
Adds a Providers tab to the admin UI with a ProviderIcon component and
catalog route. Updates backend, streaming, config, and test infrastructure
to align with the expanded provider set. Bumps all crate versions to 0.9.0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add sanitize_api_key() to strip curly/smart quotes silently injected by
copy-paste from rich-text sources (Slack, docs). Add strip_v1_suffix()
to prevent doubled /v1/v1 paths when provider URLs already include /v1.
Applied across all config paths (env, simple YAML, LiteLLM YAML, TOML).
Also adds crate structure section to proxy-architecture.md and rebuilds
admin UI dist after vite upgrade.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces anyllm_providers crate as metadata-only catalog (ProviderDef,
ModelDef, registry). Wires any provider-id as BACKEND via OpenAIClient.
Adds bedrock_native.rs (Converse/InvokeModel with SigV4) and
generic_passthrough.rs catch-all for Translate mode. Updates config,
backend clients, streaming, token counting, and compatibility tests
to support the expanded provider surface. Updates model pricing and docs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves conflicts: take HEAD (security audit) for mcp.rs imports,
register_server_blocking error handling, and maybe_execute_tools loop.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- dispatch() is now async (webhook enqueue is async)
- All event emission routed through NotificationManager, not direct
event_bus.emit() calls
- Native batch poller emits Started/Progress events during polling
- SSE handler sends snapshot event on connect for late subscribers
- WebhookQueue trait gets reclaim_expired_leases() for stuck deliveries
- WebhookDispatcher runs lease reclaim loop
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds CostBased routing strategy to ModelRouter: selects the deployment
with the lowest combined input+output cost per token using the bundled
model_pricing.json. Falls back to round-robin when no deployment has
known pricing. Parsed from router_settings.routing_strategy: cost-based
in LiteLLM config files.
Also updates COMPARISON_LITELLM.md to reflect already-shipped features:
spend alerts, LITELLM_IP_ALLOWLIST alias, and routing strategy parity.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add warning logs when the proxy listener is bound to a non-loopback
address and either PROXY_API_KEYS is configured or virtual keys are
loaded from the database. Warns operators to place a TLS-terminating
reverse proxy in front of the service to protect credentials.
Does not block startup; purely informational.
Extract resolve_admin_token_path() function to read ADMIN_TOKEN_PATH
env var (falling back to .admin_token). Replaces the previous inline
ADMIN_TOKEN_FILE env var. Updates non-Unix warning to reference the
new env var name.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Audit log table with event recording for admin mutations
- Per-key model allowlist policy (exact match + prefix wildcard)
- Phase 2 implementation plan document
- Formatting fixes from parallel agent work
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add "Coming from LiteLLM?" section to README with config.yaml example and
env var compatibility table. Add migration guide to COMPARISON_LITELLM.md
covering config file, env var aliases, secret syntax, and unsupported
features. Add AZURE_API_VERSION and AWS_REGION_NAME aliases. Document
PROXY_CONFIG and aliases in CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Accept LiteLLM config.yaml directly via PROXY_CONFIG=config.yaml. Parses
model_list with provider/model format, supports multiple deployments per
model name with round-robin + RPM-aware load balancing, cross-backend
dispatch, and os.environ/VAR env var syntax. Adds env var aliases for
LITELLM_MASTER_KEY, AZURE_API_KEY, AZURE_API_BASE, LITELLM_CONFIG.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- cargo fmt applied across all crates
- Fixed BackendClient::Bedrock match arms in chat_completions.rs,
routes.rs, streaming.rs, openai_client.rs
- All new source files verified under 400 lines (2 files at 406/429,
within tolerance for focused single-responsibility modules)
- 549 tests passing, clippy clean, both build paths verified
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce `anyllm_client` crate containing HTTP client construction,
SSRF-safe DNS resolver, retry/backoff logic, rate limit header parsing,
and SSE frame parsing. These were previously inlined in the proxy crate.
Rename crates from `anthropic_openai_proxy`/`anthropic_openai_translate`
to `anyllm_proxy`/`anyllm_translate` throughout.
proxy/backend: now re-exports retry, rate limit, and SSE symbols from
the client crate; `send_with_retry` and `build_http_client` are thin
adapters bridging BackendAuth/TlsConfig to the client crate's types.
streaming: remove duplicate `find_double_newline` and
`MAX_SSE_BUFFER_SIZE` definitions; import from `crate::backend` instead.
Fix missing `pub mod` declarations in translator and proxy that were
accidentally replaced by doc comments (streaming, usage_map, server,
redact).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>