litellm/ui/litellm-dashboard
Algirdas Č. 57090e94a4
feat!: add Hostinger Router as an OpenAI-compatible provider (#44863)
* 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>
2026-10-31 00:38:45 -07:00
..
.agents/skills/url-state feat(skills): add a litellm-setup agent skill (#47731) 2026-10-28 15:44:43 -07:00
public feat!: add Hostinger Router as an OpenAI-compatible provider (#44863) 2026-10-31 00:38:45 -07:00
scripts feat(ui): share trace drawer as a closable SidePanel and polish Lens (#44473) 2026-10-04 02:20:14 +00:00
src feat!: add Hostinger Router as an OpenAI-compatible provider (#44863) 2026-10-31 00:38:45 -07:00
tests refactor(ui): remove the deprecated Old Usage page (#49284) 2026-10-30 18:43:13 +00:00
vendor refactor(lens): connect LiteLLM to the independent Lens service (#45529) 2026-10-09 16:17:05 -07:00
.env.development
.env.production remove next env 2026-04-18 16:45:32 -07:00
.npmrc chore(build): move the Admin UI toolchain to Node 24 (#35801) 2026-08-04 12:36:07 -07:00
.nvmrc chore(build): move the Admin UI toolchain to Node 24 (#35801) 2026-08-04 12:36:07 -07:00
.prettierignore feat(ui): generate dashboard API types from the proxy OpenAPI spec (#29816) 2026-06-05 17:20:01 -07:00
.prettierrc
AGENTS.md ci: run the dashboard API types and Terraform endpoint checks on every change that can alter the spec (#49022) 2026-10-29 07:19:06 -07:00
build_release_ui.sh build release ui script 2026-01-17 18:16:14 -08:00
build_ui.sh chore(build): move the Admin UI toolchain to Node 24 (#35801) 2026-08-04 12:36:07 -07:00
build_ui_custom_path.sh chore(build): move the Admin UI toolchain to Node 24 (#35801) 2026-08-04 12:36:07 -07:00
components.json refactor(ui): switch shadcn primitives from Radix to Base UI (#32124) 2026-07-07 09:55:41 -07:00
eslint-budgets.json fix(ui): split the KeyActivityPanel condition chains to bring the lint budget back under its ceiling (#44114) 2026-10-01 18:42:12 -07:00
eslint-suppressions.json refactor(ui): remove the deprecated Old Usage page (#49284) 2026-10-30 18:43:13 +00:00
eslint.config.mjs feat(ui): replace deployment warning banners with a health icon, alert banner and panel (#46498) 2026-10-14 18:32:40 -07:00
knip.json fix(ui): register type-test files as knip entry points 2026-08-10 15:42:09 -07:00
next.config.mjs refactor(lens): connect LiteLLM to the independent Lens service (#45529) 2026-10-09 16:17:05 -07:00
package-lock.json build(deps): bump pyasn1, pypdf and minimatch to clear osv-scan (#49362) 2026-10-31 00:12:10 -07:00
package.json build(deps): bump pyasn1, pypdf and minimatch to clear osv-scan (#49362) 2026-10-31 00:12:10 -07:00
postcss.config.js feat(ui): shadcn migration foundation: Tailwind v4, shadcn init, antd cascade fix (#31995) 2026-07-02 19:02:27 -07:00
README.md
tsconfig.json test(e2e): move Admin UI Playwright suite to tests/e2e/ui (#34196) 2026-07-22 19:43:10 +00:00
tsconfig.production.json feat(traces): tracing development seed (#44363) 2026-10-03 09:59:51 +00:00
vitest.config.ts test(ui): split the vitest suite into unit, component, integration and type projects (#37488) 2026-08-19 20:40:14 +00:00

This is a Next.js project bootstrapped with create-next-app.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.

This project uses next/font to automatically optimize and load Inter, a custom Google Font.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.