mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-05 07:37:50 +00:00
fix(cloudflare): flatten content-part message arrays to a string
Cloudflare Workers AI rejects message content that is an array, so requests using OpenAI content parts failed with a type mismatch. Flatten them in _transform_messages, the way the other string-only providers do.
This commit is contained in:
parent
07a82a287b
commit
d6d584f2d7
2 changed files with 98 additions and 1 deletions
|
|
@ -1,8 +1,12 @@
|
|||
from typing import Final
|
||||
from collections.abc import Coroutine
|
||||
from typing import Final, Literal, overload
|
||||
|
||||
import httpx
|
||||
|
||||
from litellm._logging import verbose_logger
|
||||
from litellm.litellm_core_utils.prompt_templates.common_utils import (
|
||||
handle_messages_with_content_list_to_str_conversion,
|
||||
)
|
||||
from litellm.litellm_core_utils.url_utils import join_api_base
|
||||
from litellm.llms.base_llm.chat.transformation import BaseLLMException
|
||||
from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||
|
|
@ -87,6 +91,33 @@ class CloudflareChatConfig(OpenAIGPTConfig):
|
|||
api_base=api_base,
|
||||
)
|
||||
|
||||
@overload
|
||||
def _transform_messages(
|
||||
self,
|
||||
messages: list[AllMessageValues], # mutable-ok: base signature
|
||||
model: str,
|
||||
is_async: Literal[True],
|
||||
) -> Coroutine[object, object, list[AllMessageValues]]: ... # mutable-ok: base signature
|
||||
|
||||
@overload
|
||||
def _transform_messages(
|
||||
self,
|
||||
messages: list[AllMessageValues], # mutable-ok: base signature
|
||||
model: str,
|
||||
is_async: Literal[False] = False,
|
||||
) -> list[AllMessageValues]: ... # mutable-ok: base signature
|
||||
|
||||
def _transform_messages(
|
||||
self,
|
||||
messages: list[AllMessageValues], # mutable-ok: base signature
|
||||
model: str,
|
||||
is_async: bool = False,
|
||||
) -> list[AllMessageValues] | Coroutine[object, object, list[AllMessageValues]]: # mutable-ok: base signature
|
||||
flattened: Final = handle_messages_with_content_list_to_str_conversion(messages)
|
||||
if is_async:
|
||||
return super()._transform_messages(messages=flattened, model=model, is_async=True)
|
||||
return super()._transform_messages(messages=flattened, model=model, is_async=False)
|
||||
|
||||
def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> BaseLLMException:
|
||||
return CloudflareError(
|
||||
status_code=status_code,
|
||||
|
|
|
|||
|
|
@ -205,6 +205,72 @@ def test_validate_environment_sets_bearer_and_content_type():
|
|||
assert headers["Content-Type"] == "application/json"
|
||||
|
||||
|
||||
def test_transform_request_flattens_content_part_arrays_to_string():
|
||||
config = CloudflareChatConfig()
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Hello"},
|
||||
{"type": "text", "text": "More text"},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
body = config.transform_request(
|
||||
model="@cf/meta/llama-2-7b-chat-int8",
|
||||
messages=messages,
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
|
||||
assert body["messages"][0]["content"] == "HelloMore text"
|
||||
|
||||
|
||||
def test_transform_request_leaves_string_content_untouched():
|
||||
config = CloudflareChatConfig()
|
||||
messages = [
|
||||
{"role": "system", "content": "you are terse"},
|
||||
{"role": "user", "content": "weather in nyc?"},
|
||||
]
|
||||
|
||||
body = config.transform_request(
|
||||
model="@cf/meta/llama-2-7b-chat-int8",
|
||||
messages=messages,
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
|
||||
assert [m["content"] for m in body["messages"]] == ["you are terse", "weather in nyc?"]
|
||||
|
||||
|
||||
def test_async_transform_request_flattens_content_part_arrays_to_string():
|
||||
config = CloudflareChatConfig()
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Hello"},
|
||||
{"type": "text", "text": "More text"},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
body = asyncio.run(
|
||||
config.async_transform_request(
|
||||
model="@cf/meta/llama-2-7b-chat-int8",
|
||||
messages=messages,
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
)
|
||||
|
||||
assert body["messages"][0]["content"] == "HelloMore text"
|
||||
|
||||
|
||||
def _chat_response() -> dict[str, object]:
|
||||
return {
|
||||
"id": "chatcmpl-cf",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue