Skip to content

fix(embeddings): accept encoding_format="float" for vertex_ai/gemini embeddings - #33617

Merged
krrish-berri-2 merged 1 commit into
litellm_oss_daily_2026_07_16from
litellm_/vertex-embeddings-float-33293
Jul 17, 2026
Merged

fix(embeddings): accept encoding_format="float" for vertex_ai/gemini embeddings#33617
krrish-berri-2 merged 1 commit into
litellm_oss_daily_2026_07_16from
litellm_/vertex-embeddings-float-33293

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Relevant issues

Fixes #33173

Internal replacement branch for OSS PR #33293 by Mihidum Hettiyahandi (@mihidumh); original authorship is preserved on the commits

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

Captured live against a proxy on localhost:4000 at commit 6d73fcfbdc, using a real Gemini embedding model

Config:

model_list:
  - model_name: gemini-embedding
    litellm_params:
      model: gemini/gemini-embedding-001
      api_key: os.environ/GEMINI_API_KEY

encoding_format="float" (OpenAI SDK default) is now accepted and returns a real float vector:

$ curl -s -X POST http://localhost:4000/v1/embeddings -H "Authorization: Bearer sk-1234" \
    -d '{"model":"gemini-embedding","input":"hello world","encoding_format":"float"}'
{"model":"gemini-embedding","data":[{"embedding":[-0.024183841,0.0098769935,0.0074856607,-0.06730222,...]}

Other formats keep the existing unsupported-param behavior; base64 without drop_params still errors:

$ curl -s -X POST http://localhost:4000/v1/embeddings -H "Authorization: Bearer sk-1234" \
    -d '{"model":"gemini-embedding","input":"hello","encoding_format":"base64"}'
{"error":{"message":"litellm.UnsupportedParamsError: gemini does not support parameters: {'encoding_format': 'base64'}, ... To drop these, set `litellm.drop_params=True` ...","code":"400"}}

Before the fix, the float request also failed with the same UnsupportedParamsError even though float is exactly what the Vertex/Gemini embeddings API returns

Type

🐛 Bug Fix

Changes

For vertex_ai/gemini embeddings, encoding_format="float" is popped from the params before the unsupported-param check, since it is the OpenAI SDK default and a no-op for these providers (they return float lists natively). Any other value (e.g. base64) stays on the existing unsupported-param path, so it still raises unless drop_params is set

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Link to Devin session: https://app.devin.ai/sessions/2a3db9e7f3234370988a77b458d0a202

…embeddings

OpenAI SDKs (and litellm's own client since ~1.84) send
encoding_format='float' by default, but the vertex embedding config only
supports ['dimensions'], so get_optional_params_embeddings raised
UnsupportedParamsError at the provider default value. Any
OpenAI-compatible client talking to a litellm proxy with vertex
embedding models got a 400 unless the operator set proxy-wide
drop_params: true.

Float lists are exactly what the vertex API returns, so the param is a
no-op: pop it before validation. Other values (e.g. 'base64') keep the
existing unsupported-param behavior (dropped with drop_params, raise
otherwise).

Fixes #33173

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a usability regression where encoding_format="float" — the OpenAI SDK default — was incorrectly rejected with UnsupportedParamsError for vertex_ai and gemini embedding calls, even though these providers natively return float lists. The fix strips the param before the unsupported-param check so the default passes silently; all other values (e.g. base64) continue on the existing error/drop path.

  • Adds 6 lines in the existing vertex_ai/gemini branch of get_optional_params_embeddings in utils.py to pop encoding_format="float" before validation.
  • Includes five targeted unit tests covering both providers, both accept and reject cases, drop_params behaviour, and downstream dimensions mapping — all properly mocked.

Confidence Score: 4/5

Safe to merge; the change is a small, well-tested no-op strip of a default parameter that previously caused a spurious error.

The functional fix is correct and the tests are thorough. The one concern is placement: the stripping logic lives in utils.py rather than in VertexAITextEmbeddingConfig where provider-specific transform logic belongs. If vertex_ai or gemini ever gain a BaseEmbeddingConfig registration in get_provider_embedding_config, the early-return path would bypass these lines entirely and the bug would silently reappear. The fix works today but is fragile by design.

litellm/utils.py — the new strip logic sits inside the legacy elif custom_llm_provider == "vertex_ai" block; consider moving it to VertexAITextEmbeddingConfig.map_openai_params() in litellm/llms/vertex_ai/vertex_embeddings/transformation.py

Important Files Changed

Filename Overview
litellm/utils.py Adds 6 lines in the existing vertex_ai/gemini embedding branch to pop encoding_format="float" from non_default_params before the unsupported-param check; logic is correct but placed in utils.py rather than the provider config class where it belongs
tests/test_litellm/test_utils.py Adds five focused unit tests covering float accepted/dropped for both vertex_ai and gemini providers, base64 rejected without drop_params, base64 dropped with drop_params, and dimensions still mapped — all mocked, no network calls

Reviews (1): Last reviewed commit: "fix(embeddings): accept encoding_format=..." | Re-trigger Greptile

Comment thread litellm/utils.py
Comment on lines 3199 to +3205
elif custom_llm_provider == "vertex_ai" or custom_llm_provider == "gemini":
# OpenAI SDKs (and litellm's own client) send encoding_format="float"
# by default; float lists are exactly what the vertex API returns, so
# the param is a no-op — don't reject the provider default. Other
# values (e.g. "base64") stay on the unsupported-param path below.
if non_default_params.get("encoding_format") == "float":
non_default_params.pop("encoding_format")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Provider-specific logic placed outside llms/ directory

The encoding-format stripping is added directly to utils.py rather than to the provider's own config class. VertexAITextEmbeddingConfig (in litellm/llms/vertex_ai/vertex_embeddings/transformation.py) already owns both get_supported_openai_params() and map_openai_params() — the correct fix is to add "encoding_format" to the supported-params list and silently drop it (when "float") inside map_openai_params(). Placing the strip logic in utils.py means the behaviour won't automatically apply when the provider eventually gets a BaseEmbeddingConfig registration in get_provider_embedding_config (the early-return path would then bypass these lines entirely).

Rule Used: What: Avoid writing provider-specific code outside... (source)

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Tested live against a local proxy on localhost:4000 hitting the real Gemini API (config: gemini/gemini-embedding-001, drop_params: false)

curl -s -X POST http://localhost:4000/v1/embeddings \
  -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"model":"gemini-embedding","input":"hello","encoding_format":"float"}'
# HTTP 200
{"model":"gemini-embedding","data":[{"embedding":[-0.024183841,0.0098769935,0.0074856607,-0.06730222,...]}]}

curl -s -X POST http://localhost:4000/v1/embeddings \
  -H "Authorization: Bearer sk-1234" -H "Content-Type: application/json" \
  -d '{"model":"gemini-embedding","input":"hello","encoding_format":"base64"}'
{"error":{"message":"litellm.UnsupportedParamsError: gemini does not support parameters: {'encoding_format': 'base64'} ... To drop these, set `litellm.drop_params=True`", ...}}

encoding_format="float" now returns a real Gemini vector, and base64 still errors without drop_params, so the fix is correctly scoped to float only

live proxy output

Full walkthrough and test report: https://app.devin.ai/sessions/2a3db9e7f3234370988a77b458d0a202

@krrish-berri-2
krrish-berri-2 merged commit 69a476f into litellm_oss_daily_2026_07_16 Jul 17, 2026
96 of 97 checks passed
@krrish-berri-2
krrish-berri-2 deleted the litellm_/vertex-embeddings-float-33293 branch July 17, 2026 02:09
yuneng-berri added a commit that referenced this pull request Jul 17, 2026
* fix(embeddings): accept encoding_format='float' for vertex_ai/gemini embeddings (#33617)

OpenAI SDKs (and litellm's own client since ~1.84) send
encoding_format='float' by default, but the vertex embedding config only
supports ['dimensions'], so get_optional_params_embeddings raised
UnsupportedParamsError at the provider default value. Any
OpenAI-compatible client talking to a litellm proxy with vertex
embedding models got a 400 unless the operator set proxy-wide
drop_params: true.

Float lists are exactly what the vertex API returns, so the param is a
no-op: pop it before validation. Other values (e.g. 'base64') keep the
existing unsupported-param behavior (dropped with drop_params, raise
otherwise).

Fixes #33173

Co-authored-by: Mihidum Hettiyahandi <55163074+mihidumh@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat(guardrails): add Singulr guardrail integration for LiteLLM gateway (#31302)

* singulr guardrail support for litellm gateway

* Update litellm/proxy/guardrails/guardrail_hooks/singulr/singulr.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix comments

* improvement

* fix: resolve review comments and implement requested improvements

* fix:Guardrail bypass through uninspected messages

* fix:tool text scanning

* fix: Legacy function definitions bypass scanning by adding indirect message scaning

* chore: remove unintended basedpyright budget file

* fix:Response schema bypasses guardrail scanning (response_format.json_schema)

* chore: restore basedpyright-code-budget.json and update lint baselines

Restores the file deleted in c698b88 to match upstream litellm_internal_staging.
Regenerates basedpyright and ruff-strict budget baselines via make lint-budget-update.

* fix: scan system messages as indirect prompt injection in Singulr guardrail

* chore: restore lint budget files to upstream baseline

* fix: resolve ruff UP006 and I001 violations in singulr guardrail

* Update litellm/proxy/guardrails/guardrail_hooks/singulr/singulr.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* resolve review comments on Singulr guardrail

* fix: scan tool call results as indirect prompt injection in Singulr guardrail

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* minor

* formating fix

* refactor: shift extraction logic to singulr side

* refactor:keep precall hook only

* fix:formatting

* fix:linting

* improve config description

* Trigger CI

* fix

* fix:field description

* fix:errors due to change in field names

* style: apply ruff line-wrap formatting to singulr guardrail

* fix:exception

* fix:formatting

* fix playground

* improved

* Update litellm/proxy/guardrails/guardrail_hooks/singulr/singulr.py

Co-authored-by: veria-ai[bot] <224490171+veria-ai[bot]@users.noreply.github.com>

* Update litellm/proxy/guardrails/guardrail_hooks/singulr/singulr.py

Co-authored-by: veria-ai[bot] <224490171+veria-ai[bot]@users.noreply.github.com>

* fix

* fix ci issues

* remove uv.lock from pr

* fix

* fix:resolved comments

* chore: trigger CI

* remove uv.lock

* fix

* fix linting

* fix linting

* fix linting

* remove doc strings

* remove test fixes

* chore: retrigger CI

* change in singulr api contract

* remove some ut

* send litellm call_id to singulr

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: aniket-kardile <aniket.kardile@singulr.ai>
Co-authored-by: veria-ai[bot] <224490171+veria-ai[bot]@users.noreply.github.com>

* Fix non-conformant UUIDv7 generation in native Opik integration (#31294)

create_uuid7() encoded the timestamp in units of 16 seconds instead of
milliseconds, so the top 48 bits came out ~4096x the real unix-ms. Opik's
backend validates the embedded UUIDv7 timestamp on ingestion (OPIK-7067);
the bad encoding decoded to ~year 2201 and every trace/span batch was
rejected with HTTP 400.

Rewrite create_uuid7() to be RFC 9562 conformant (top 48 bits = unix-ms),
using the standard library only so no new dependency is added. Add unit
tests covering UUIDv7 validity and millisecond timestamp encoding.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(proxy): expose uvicorn concurrency limit (#33077)

Expose uvicorn's limit_concurrency as a --limit_concurrency CLI flag and
LIMIT_CONCURRENCY environment variable. Uvicorn counts both active tasks and
accepted connections and returns HTTP 503 once the configured limit is reached.

Reject non-positive limits at CLI parse time and only add the setting to the
uvicorn startup arguments. Because idle connections also consume capacity,
deployments should use upstream connection/header timeouts and per-client
connection limits.

* test: reorder test_utils tail to keep the daily merge conflict-free (#33788)

The daily OSS branch and litellm_internal_staging each appended an
independent test block at the very end of tests/test_litellm/test_utils.py,
so merging the two collides on that shared end-of-file position even though
the additions are unrelated (this branch adds the vertex embedding
encoding-format tests; staging adds the per-model prompt-cache-minimum
tests). Moving this branch's new TestVertexEmbeddingEncodingFormat class
above test_gemini_image_models_do_not_support_reasoning, which both branches
share, gives the two additions different anchors, so git applies both
without a conflict and without pulling staging into this branch. Pure
reorder; no test bodies change

---------

Co-authored-by: Mateo Wang <277851410+mateo-berri@users.noreply.github.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Mihidum Hettiyahandi <55163074+mihidumh@users.noreply.github.com>
Co-authored-by: madan-singulr <150280287+madan-singulr@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: aniket-kardile <aniket.kardile@singulr.ai>
Co-authored-by: veria-ai[bot] <224490171+veria-ai[bot]@users.noreply.github.com>
Co-authored-by: Aliaksandr Kuzmik <98702584+alexkuzmik@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Salva Madrid <50212436+salvamadrid@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants