Skip to content

Commit 72b492c

Browse files
committed
Fix Bedrock Titan V2 encoding_format parameter support
- Add encoding_format to supported OpenAI parameters list - Implement encoding_format to embeddingTypes parameter mapping - Map 'float' to ['float'] and 'base64' to ['binary'] formats - Handle response with proper fallback: binary > float > embedding field - Support both float and binary response formats per AWS documentation Fixes #14685 - UnsupportedParamsError when using encoding_format with Titan V2
1 parent 0e096d7 commit 72b492c

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

litellm/llms/bedrock/embed/amazon_titan_v2_transformation.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"""
1111

1212
import types
13-
from typing import List, Optional
13+
from typing import List, Optional, Union
1414

1515
from litellm.types.llms.bedrock import (
1616
AmazonTitanV2EmbeddingRequest,
@@ -30,9 +30,7 @@ class AmazonTitanV2Config:
3030
normalize: Optional[bool] = None
3131
dimensions: Optional[int] = None
3232

33-
def __init__(
34-
self, normalize: Optional[bool] = None, dimensions: Optional[int] = None
35-
) -> None:
33+
def __init__(self, normalize: Optional[bool] = None, dimensions: Optional[int] = None) -> None:
3634
locals_ = locals().copy()
3735
for key, value in locals_.items():
3836
if key != "self" and value is not None:
@@ -57,32 +55,56 @@ def get_config(cls):
5755
}
5856

5957
def get_supported_openai_params(self) -> List[str]:
60-
return ["dimensions"]
58+
return ["dimensions", "encoding_format"]
6159

62-
def map_openai_params(
63-
self, non_default_params: dict, optional_params: dict
64-
) -> dict:
60+
def map_openai_params(self, non_default_params: dict, optional_params: dict) -> dict:
6561
for k, v in non_default_params.items():
6662
if k == "dimensions":
6763
optional_params["dimensions"] = v
64+
elif k == "encoding_format":
65+
# Map OpenAI encoding_format to AWS embeddingTypes
66+
if v == "float":
67+
optional_params["embeddingTypes"] = ["float"]
68+
elif v == "base64":
69+
# base64 maps to binary format in AWS
70+
optional_params["embeddingTypes"] = ["binary"]
71+
else:
72+
# For any other encoding format, default to float
73+
optional_params["embeddingTypes"] = ["float"]
6874
return optional_params
6975

70-
def _transform_request(
71-
self, input: str, inference_params: dict
72-
) -> AmazonTitanV2EmbeddingRequest:
76+
def _transform_request(self, input: str, inference_params: dict) -> AmazonTitanV2EmbeddingRequest:
7377
return AmazonTitanV2EmbeddingRequest(inputText=input, **inference_params) # type: ignore
7478

75-
def _transform_response(
76-
self, response_list: List[dict], model: str
77-
) -> EmbeddingResponse:
79+
def _transform_response(self, response_list: List[dict], model: str) -> EmbeddingResponse:
7880
total_prompt_tokens = 0
7981

8082
transformed_responses: List[Embedding] = []
8183
for index, response in enumerate(response_list):
8284
_parsed_response = AmazonTitanV2EmbeddingResponse(**response) # type: ignore
85+
86+
# According to AWS docs, embeddingsByType is always present
87+
# If binary was requested (encoding_format="base64"), use binary data
88+
# Otherwise, use float data from embeddingsByType or fallback to embedding field
89+
embedding_data: Union[List[float], List[int]]
90+
91+
if ("embeddingsByType" in _parsed_response and
92+
"binary" in _parsed_response["embeddingsByType"]):
93+
# Use binary data if available (for encoding_format="base64")
94+
embedding_data = _parsed_response["embeddingsByType"]["binary"]
95+
elif ("embeddingsByType" in _parsed_response and
96+
"float" in _parsed_response["embeddingsByType"]):
97+
# Use float data from embeddingsByType
98+
embedding_data = _parsed_response["embeddingsByType"]["float"]
99+
elif "embedding" in _parsed_response:
100+
# Fallback to legacy embedding field
101+
embedding_data = _parsed_response["embedding"]
102+
else:
103+
raise ValueError(f"No embedding data found in response: {response}")
104+
83105
transformed_responses.append(
84106
Embedding(
85-
embedding=_parsed_response["embedding"],
107+
embedding=embedding_data,
86108
index=index,
87109
object="embedding",
88110
)

0 commit comments

Comments
 (0)