From 63b57f899e7c1774af021dbe5b89875faf346523 Mon Sep 17 00:00:00 2001 From: udbhav-shrinet Date: Wed, 14 Oct 2026 03:20:54 +0530 Subject: [PATCH 1/5] fix(utils): align get_formatted_prompt call_type Literal with CallTypesLiteral (#46165) --- .../get_formatted_prompt.py | 39 ++++++++++++------- .../test_get_formatted_prompt.py | 20 +++++++++- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py index 2c1befb7ac3..b86f0df23b5 100644 --- a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py +++ b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py @@ -7,10 +7,17 @@ def get_formatted_prompt( "acompletion", "completion", "embedding", + "aembedding", + "embeddings", "image_generation", + "aimage_generation", "audio_transcription", + "transcription", + "atranscription", "moderation", + "amoderation", "text_completion", + "atext_completion", ], ) -> str: """ @@ -19,32 +26,38 @@ def get_formatted_prompt( Returns a string. """ prompt = "" - if call_type == "acompletion" or call_type == "completion": - for message in data["messages"]: + if call_type in ("acompletion", "completion"): + for message in data.get("messages", []): if message.get("content", None) is not None: content = message.get("content") if isinstance(content, str): prompt += message["content"] elif isinstance(content, list): for c in content: - if c["type"] == "text": - prompt += c["text"] + if isinstance(c, dict) and c.get("type") == "text": + prompt += c.get("text", "") if "tool_calls" in message: for tool_call in message["tool_calls"] or (): if "function" in tool_call: function_arguments = tool_call["function"]["arguments"] prompt += function_arguments - elif call_type == "text_completion": - prompt = data["prompt"] - elif call_type == "embedding" or call_type == "moderation": - if isinstance(data["input"], str): + elif call_type in ("text_completion", "atext_completion"): + prompt = data.get("prompt", "") + elif call_type in ( + "embedding", + "aembedding", + "embeddings", + "moderation", + "amoderation", + ): + if isinstance(data.get("input"), str): prompt = data["input"] - elif isinstance(data["input"], list): + elif isinstance(data.get("input"), list): for m in data["input"]: - prompt += m - elif call_type == "image_generation": - prompt = data["prompt"] - elif call_type == "audio_transcription": + prompt += str(m) + elif call_type in ("image_generation", "aimage_generation"): + prompt = data.get("prompt", "") + elif call_type in ("audio_transcription", "transcription", "atranscription"): if "prompt" in data: prompt = data["prompt"] return prompt diff --git a/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py b/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py index 64dd79bb918..35234ad84f6 100644 --- a/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py +++ b/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py @@ -1,4 +1,4 @@ -from typing import Final, Literal +from typing import Any, Final, Literal import pytest @@ -22,3 +22,21 @@ def test_null_tool_calls_are_skipped(call_type: Literal["acompletion", "completi } assert get_formatted_prompt(data=data, call_type=call_type) == 'pingpong{"x":1}' + + +@pytest.mark.parametrize( + ("data", "call_type", "expected"), + [ + ({"prompt": "transcribe speech"}, "transcription", "transcribe speech"), + ({"prompt": "async speech"}, "atranscription", "async speech"), + ({"prompt": "audio legacy"}, "audio_transcription", "audio legacy"), + ({"input": "embed async"}, "aembedding", "embed async"), + ({"input": ["embed", "dings"]}, "embeddings", "embeddings"), + ({"input": "mod async"}, "amoderation", "mod async"), + ({"prompt": "gen image async"}, "aimage_generation", "gen image async"), + ({"prompt": "complete async"}, "atext_completion", "complete async"), + ], +) +def test_get_formatted_prompt_call_types(data: dict[str, Any], call_type: Any, expected: str) -> None: + assert get_formatted_prompt(data=data, call_type=call_type) == expected + From 61e41752bb8795047dc360da5907ef016509f161 Mon Sep 17 00:00:00 2001 From: udbhav-shrinet Date: Fri, 23 Oct 2026 11:30:26 +0530 Subject: [PATCH 2/5] fix(utils): tighten get_formatted_prompt types and guard non-str inputs --- .../get_formatted_prompt.py | 49 ++++++++++--------- .../test_get_formatted_prompt.py | 19 +++++-- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py index b86f0df23b5..15c2b7cb20f 100644 --- a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py +++ b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py @@ -26,38 +26,43 @@ def get_formatted_prompt( Returns a string. """ prompt = "" - if call_type in ("acompletion", "completion"): - for message in data.get("messages", []): + if call_type == "acompletion" or call_type == "completion": + for message in data["messages"]: if message.get("content", None) is not None: content = message.get("content") if isinstance(content, str): prompt += message["content"] elif isinstance(content, list): for c in content: - if isinstance(c, dict) and c.get("type") == "text": - prompt += c.get("text", "") + if c["type"] == "text": + prompt += c["text"] if "tool_calls" in message: for tool_call in message["tool_calls"] or (): if "function" in tool_call: function_arguments = tool_call["function"]["arguments"] prompt += function_arguments - elif call_type in ("text_completion", "atext_completion"): - prompt = data.get("prompt", "") - elif call_type in ( - "embedding", - "aembedding", - "embeddings", - "moderation", - "amoderation", + elif call_type == "text_completion" or call_type == "atext_completion": + prompt = data["prompt"] + elif ( + call_type == "embedding" + or call_type == "aembedding" + or call_type == "embeddings" + or call_type == "moderation" + or call_type == "amoderation" ): - if isinstance(data.get("input"), str): - prompt = data["input"] - elif isinstance(data.get("input"), list): - for m in data["input"]: - prompt += str(m) - elif call_type in ("image_generation", "aimage_generation"): - prompt = data.get("prompt", "") - elif call_type in ("audio_transcription", "transcription", "atranscription"): - if "prompt" in data: - prompt = data["prompt"] + if "input" in data: + if isinstance(data["input"], str): + prompt = data["input"] + elif isinstance(data["input"], list): + for m in data["input"]: + if isinstance(m, str): + prompt += m + elif call_type == "image_generation" or call_type == "aimage_generation": + prompt = data["prompt"] + elif ( + call_type == "audio_transcription" + or call_type == "transcription" + or call_type == "atranscription" + ) and "prompt" in data: + prompt = data["prompt"] return prompt diff --git a/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py b/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py index 35234ad84f6..02b89d15236 100644 --- a/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py +++ b/tests/unit/litellm_core_utils/llm_response_utils/test_get_formatted_prompt.py @@ -1,4 +1,4 @@ -from typing import Any, Final, Literal +from typing import Final, Literal import pytest @@ -6,6 +6,18 @@ from litellm.litellm_core_utils.llm_response_utils.get_formatted_prompt import ( get_formatted_prompt, ) +CallType = Literal[ + "transcription", + "atranscription", + "audio_transcription", + "aembedding", + "embedding", + "embeddings", + "amoderation", + "aimage_generation", + "atext_completion", +] + @pytest.mark.parametrize("call_type", ["acompletion", "completion"]) def test_null_tool_calls_are_skipped(call_type: Literal["acompletion", "completion"]) -> None: @@ -32,11 +44,12 @@ def test_null_tool_calls_are_skipped(call_type: Literal["acompletion", "completi ({"prompt": "audio legacy"}, "audio_transcription", "audio legacy"), ({"input": "embed async"}, "aembedding", "embed async"), ({"input": ["embed", "dings"]}, "embeddings", "embeddings"), + ({"input": [0.1, 0.2]}, "aembedding", ""), + ({"input": [101, 2054]}, "embedding", ""), ({"input": "mod async"}, "amoderation", "mod async"), ({"prompt": "gen image async"}, "aimage_generation", "gen image async"), ({"prompt": "complete async"}, "atext_completion", "complete async"), ], ) -def test_get_formatted_prompt_call_types(data: dict[str, Any], call_type: Any, expected: str) -> None: +def test_get_formatted_prompt_call_types(data: dict[str, object], call_type: CallType, expected: str) -> None: assert get_formatted_prompt(data=data, call_type=call_type) == expected - From 39801f7d665600641de1cc2a2327ab240be75f4a Mon Sep 17 00:00:00 2001 From: udbhav-shrinet Date: Fri, 23 Oct 2026 15:21:45 +0530 Subject: [PATCH 3/5] style: format get_formatted_prompt with ruff --- .../llm_response_utils/get_formatted_prompt.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py index 15c2b7cb20f..ec58573b92a 100644 --- a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py +++ b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py @@ -60,9 +60,7 @@ def get_formatted_prompt( elif call_type == "image_generation" or call_type == "aimage_generation": prompt = data["prompt"] elif ( - call_type == "audio_transcription" - or call_type == "transcription" - or call_type == "atranscription" + call_type == "audio_transcription" or call_type == "transcription" or call_type == "atranscription" ) and "prompt" in data: prompt = data["prompt"] return prompt From 9a97969741f57cb2ca70e7dc599bc261a875f4b9 Mon Sep 17 00:00:00 2001 From: udbhav-shrinet Date: Fri, 23 Oct 2026 15:29:45 +0530 Subject: [PATCH 4/5] style: satisfy ruff SIM114 branch combine rule --- .../llm_response_utils/get_formatted_prompt.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py index ec58573b92a..dd8b539e973 100644 --- a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py +++ b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py @@ -57,10 +57,11 @@ def get_formatted_prompt( for m in data["input"]: if isinstance(m, str): prompt += m - elif call_type == "image_generation" or call_type == "aimage_generation": - prompt = data["prompt"] elif ( - call_type == "audio_transcription" or call_type == "transcription" or call_type == "atranscription" - ) and "prompt" in data: + call_type == "image_generation" + or call_type == "aimage_generation" + or (call_type == "audio_transcription" or call_type == "transcription" or call_type == "atranscription") + and "prompt" in data + ): prompt = data["prompt"] return prompt From d2492eb7e4fba8a1bc9417d1c03d8dab9d966918 Mon Sep 17 00:00:00 2001 From: udbhav-shrinet Date: Fri, 23 Oct 2026 15:37:43 +0530 Subject: [PATCH 5/5] style: use set membership to satisfy strict ruff PLR1714 --- .../llm_response_utils/get_formatted_prompt.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py index dd8b539e973..2db92812803 100644 --- a/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py +++ b/litellm/litellm_core_utils/llm_response_utils/get_formatted_prompt.py @@ -26,7 +26,7 @@ def get_formatted_prompt( Returns a string. """ prompt = "" - if call_type == "acompletion" or call_type == "completion": + if call_type in {"acompletion", "completion"}: for message in data["messages"]: if message.get("content", None) is not None: content = message.get("content") @@ -41,15 +41,9 @@ def get_formatted_prompt( if "function" in tool_call: function_arguments = tool_call["function"]["arguments"] prompt += function_arguments - elif call_type == "text_completion" or call_type == "atext_completion": + elif call_type in {"text_completion", "atext_completion"}: prompt = data["prompt"] - elif ( - call_type == "embedding" - or call_type == "aembedding" - or call_type == "embeddings" - or call_type == "moderation" - or call_type == "amoderation" - ): + elif call_type in {"embedding", "aembedding", "embeddings", "moderation", "amoderation"}: if "input" in data: if isinstance(data["input"], str): prompt = data["input"] @@ -58,9 +52,8 @@ def get_formatted_prompt( if isinstance(m, str): prompt += m elif ( - call_type == "image_generation" - or call_type == "aimage_generation" - or (call_type == "audio_transcription" or call_type == "transcription" or call_type == "atranscription") + call_type in {"image_generation", "aimage_generation"} + or (call_type in {"audio_transcription", "transcription", "atranscription"}) and "prompt" in data ): prompt = data["prompt"]