Files
whit3rabbitandClaude c90fb9f640 feat: loopback-open auth default, --port flag, max_tokens fix, UI banner
- 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>
2026-07-16 20:08:13 -05:00
..
2026-06-20 15:24:43 -05:00

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 system to OpenAI developer role or Responses instructions)
  • 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)

This crate is part of anyllm-proxy, which also includes a standalone HTTP proxy server.