mirror of
https://github.com/whit3rabbit/anyllm-proxy.git
synced 2026-09-22 00:00:50 +00:00
- 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>
anyllm_translate
Pure, IO-free translation between Anthropic Messages API and OpenAI Chat Completions / Responses API formats. Also supports Google Gemini native API translation.
No HTTP clients, no async runtime, no network calls. Just fn(A) -> B transformations.
Quick Start
use anyllm_translate::{TranslationConfig, translate_request, translate_response};
use anyllm_translate::anthropic::MessageCreateRequest;
let config = TranslationConfig::builder()
.model_map("haiku", "gpt-4o-mini")
.model_map("sonnet", "gpt-4o")
.model_map("opus", "gpt-4o")
.build();
let req: MessageCreateRequest = serde_json::from_str(r#"{
"model": "claude-sonnet-4-6",
"max_tokens": 100,
"messages": [{"role": "user", "content": "Hello"}]
}"#).unwrap();
let openai_req = translate_request(&req, &config).unwrap();
assert_eq!(openai_req.model, "gpt-4o");
// Send openai_req to OpenAI, get response, then:
// let anthropic_resp = translate_response(&openai_resp, &req.model);
Supported APIs
- Anthropic Messages API (request/response types, streaming SSE events)
- OpenAI Chat Completions API (request/response types, streaming chunks)
- OpenAI Responses API (request/response types, streaming events)
- Google Gemini native API (generateContent types, streaming)
Features
- Default: Pure translation types and mapping functions
middleware: Adds an axum middleware layer that intercepts Anthropic-format requests, translates them, forwards to a configurable backend, and translates responses back
[dependencies]
anyllm_translate = "0.1"
# With middleware support:
anyllm_translate = { version = "0.1", features = ["middleware"] }
Modules
| Module | Description |
|---|---|
anthropic |
Anthropic Messages API types (request, response, streaming, errors) |
openai |
OpenAI Chat Completions and Responses API types |
gemini |
Google Gemini native API types |
mapping |
Stateless conversion functions between APIs |
config |
Translation configuration (model mapping, lossy behavior) |
translate |
Convenience wrappers combining config with mapping |
middleware |
Axum middleware layer (requires middleware feature) |
Translation Coverage
- Text messages, multi-turn conversations
- System prompts (Anthropic
systemto OpenAIdeveloperrole or Responsesinstructions) - Tool definitions, tool calls, tool results
- Image and document content blocks (documents degrade to text notes)
- Streaming SSE event translation (state machines for each backend)
- Token usage mapping
- Error type/status code translation
- Extended thinking (stripped when targeting OpenAI)
Related
This crate is part of anyllm-proxy, which also includes a standalone HTTP proxy server.