mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-01 07:03:02 +00:00
* feat: add Hostinger Router as an OpenAI-compatible provider Adds hostinger_router (https://router.hostinger.com/v1) to the JSON-configured openai_like providers with chat completions, responses, messages, and embeddings endpoints, cost-map entries for claude-sonnet-5, gpt-5.2 and the two text-embedding-3 models (credits converted at 1 credit = $0.01, sourced from the public https://router.hostinger.com/v1/models catalog), the endpoint-support matrix, Admin UI add-model form fields and logo, and respx-mocked unit tests covering all declared endpoints. Also routes /v1/embeddings for JSON-configured providers that declare it in providers.json; previously embedding calls for these providers fell through to LiteLLMUnknownProvider. * fix(hostinger_router): match prices to the live catalog, drop retired max_tokens, regenerate the endpoint matrix * fix(hostinger_router): keep api_base detection off, send embeddings headers as HTTP headers, drop generic key fallback Unprefixed models called with Hostinger's api_base keep their own provider, JSON provider embeddings no longer borrow OPENAI_LIKE_API_KEY or litellm.api_key, and the openai_like embedding handler sends extra_headers as request headers instead of in the JSON body * fix(openai_like): route Hostinger messages and responses per model, keep the configured key header Native /v1/messages and /v1/responses calls for a JSON provider now also follow the model's cost-map supported_endpoints, so Hostinger models without the route go through chat completions instead of a 403. Embedding key headers replace extra_headers case-insensitively, and pinstripes stops declaring /v1/embeddings. * fix(openai_like): let embeddings extra_headers override the key's headers as chat does Embeddings now match chat through the OpenAI SDK, so an extra_headers entry replaces the key's header of the same name in any letter case. The Hostinger capability test checks that the supports_* lookups agree with each cost-map row instead of pinning vendor flags * fix(openai_like): send numeric embeddings extra_headers as text and keep Hostinger's 1h cache TTL A config.yaml header like X-Org-Id: 12345 loads as an int, which the embeddings header check rejected with a 500. Int and float values now go out as their decimal text. Hostinger Router accepts and bills a 1h cache_control TTL on /v1/messages, so its provider entry opts into keeping it. * fix(openai_like): send Hostinger's 1h cache TTL as the 5-minute default so cache writes bill at its charge * fix(openai_like): route Hostinger natives per model from providers.json, refuse non-text embeddings headers unless drop_params * fix(openai_like): refuse Host, Content-Length and Transfer-Encoding in embeddings extra_headers unless drop_params * fix(openai_like): refuse malformed embeddings extra_headers and ignore transport headers Header names must be HTTP tokens and values printable ASCII on one line, so a colon in a name or a line break in a value answers 400 unless drop_params drops it. Host, Content-Length and Transfer-Encoding are ignored, since a 400 for them sends the call to the deployment's fallback with the same headers. * fix(openai_like): trim embeddings extra_headers values and drop values HTTP cannot carry HTTP ignores spaces and tabs around a header value, so values are trimmed before they are sent. A value that is not printable ASCII on one line after trimming is dropped with a warning instead of failing the call, since the proxy adds headers itself from key aliases and forwarded client headers that the caller cannot fix. A malformed header name or a non-text value still answers 400 unless drop_params drops it. * fix(openai_like): ignore hop-by-hop extra_headers and trim line breaks around values TE, Upgrade, Connection, Keep-Alive, Proxy-Connection and Trailer in extra_headers are now ignored like Host, Content-Length and Transfer-Encoding, since litellm builds the request and TE: gzip fails HTTP/2 while Upgrade makes some upstreams hang. Line breaks at the ends of a value are trimmed along with spaces and tabs, so a secret read from a file with a trailing newline is sent instead of dropped. The drop warning now names the model. * fix(embeddings): keep one request's extra_headers out of the deployment's headers and ignore Expect embedding() merged a request's extra_headers into the headers dict it got from the deployment's litellm_params. The router only shallow-copies those params, so the merge wrote the caller's headers into the deployment itself, and later embeddings calls through that deployment sent them too. Build a new dict instead, and drop the None checks that can no longer be true. Also treat Expect as a transport header that hostinger_router embeddings never forwards, and name the model with %r in the dropped-value warning. * fix(embeddings): keep name and value pairs working in headers and answer 400 for other non-object values The previous commit merged headers and extra_headers with dict unpacking, which only takes a mapping, so a list of name and value pairs that dict.update used to accept now raised a TypeError and the proxy answered 500. Merge through dict() so pairs keep working, and answer 400 for any other value, or drop it under drop_params, as the litellm convention does for an unsupported param. --------- Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| _support | ||
| audio_tests | ||
| base_sdk_tests | ||
| benchmarks | ||
| code_coverage_tests | ||
| documentation_tests | ||
| e2e | ||
| e2e_harness | ||
| fixtures | ||
| harness_e2e | ||
| integration | ||
| rust-python-harness | ||
| test_litellm_rust | ||
| typing | ||
| unit | ||
| windows_tests | ||
| __init__.py | ||
| _fake_openai_endpoint_server.py | ||
| _flush_vcr_cache.py | ||
| _live_test_helpers.py | ||
| _master_key.py | ||
| _openai_record_replay_proxy.py | ||
| _process_helpers.py | ||
| _vcr_conftest_common.py | ||
| _vcr_redis_persister.py | ||
| _wait_helpers.py | ||
| _ws_vcr.py | ||
| AGENTS.md | ||
| capturing_transport.py | ||
| eval_swe_bench.py | ||
| fake_openai_endpoint.py | ||
| gettysburg.wav | ||
| large_text.py | ||
| openai_batch_completions.jsonl | ||
| pyrightconfig.json | ||
| README.MD | ||
| test_logging.conf | ||
| test_rust_python_harness.py | ||
| VCR_TESTING.md | ||
| white_100x100.png | ||
In total litellm runs 1000+ tests
[02/20/2025] Update:
To make it easier to contribute and map what behavior is tested,
we've started mapping the litellm directory in tests/unit
This folder can only run mock tests.