mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-07 07:58:09 +00:00
fix(completion): surface a non-streaming upstream abort as a server error
This commit is contained in:
parent
c7c895db45
commit
cea101402d
2 changed files with 39 additions and 0 deletions
|
|
@ -422,6 +422,7 @@ class _PromptCacheTokenCounts(TypedDict, total=False):
|
|||
_CACHED_MESSAGE_PROVIDER_FIELDS: Final = TypeAdapter(_CachedMessageProviderFields)
|
||||
_CACHED_USAGE_DETAILS: Final = TypeAdapter(_CachedUsageDetails)
|
||||
_FIELD_MAP: Final = TypeAdapter(dict[str, object])
|
||||
_CHOICE_FIELD_MAPS: Final = TypeAdapter(list[dict[str, object]])
|
||||
_COMPLETION_TOKENS_DETAILS: Final = TypeAdapter(CompletionTokensDetailsWrapper)
|
||||
_PROMPT_TOKENS_DETAILS: Final = TypeAdapter(PromptTokensDetailsWrapper)
|
||||
_PROMPT_CACHE_TOKEN_COUNTS: Final = TypeAdapter(_PromptCacheTokenCounts)
|
||||
|
|
@ -757,6 +758,20 @@ def convert_to_model_response_object(
|
|||
model="",
|
||||
)
|
||||
|
||||
response_fields: Final = _FIELD_MAP.validate_python(response_object)
|
||||
if any(
|
||||
choice.get("finish_reason") == "abort"
|
||||
for choice in _CHOICE_FIELD_MAPS.validate_python(response_fields["choices"])
|
||||
):
|
||||
from litellm.exceptions import APIError
|
||||
|
||||
raise APIError(
|
||||
status_code=500,
|
||||
message="Upstream generation aborted (finish_reason=abort)",
|
||||
llm_provider="",
|
||||
model=str(response_fields.get("model") or ""),
|
||||
)
|
||||
|
||||
for idx, choice in enumerate(response_object["choices"]):
|
||||
## HANDLE JSON MODE - anthropic returns single function call]
|
||||
tool_calls = choice["message"].get("tool_calls", None)
|
||||
|
|
|
|||
|
|
@ -228,6 +228,30 @@ def test_convert_missing_choices_raises_api_error() -> None:
|
|||
assert "no 'choices'" in str(exc_info.value)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("finish_reasons", [("abort",), ("stop", "abort"), ("abort", "stop")])
|
||||
def test_convert_aborted_choice_raises_api_error(finish_reasons: tuple[str, ...]) -> None:
|
||||
from litellm.exceptions import APIError
|
||||
|
||||
resp: Final = {
|
||||
"id": "x",
|
||||
"created": 1,
|
||||
"model": "Qwen/Qwen3-8B",
|
||||
"object": "chat.completion",
|
||||
"choices": [
|
||||
{"index": index, "message": {"role": "assistant", "content": "Oslo is 4C and"}, "finish_reason": reason}
|
||||
for index, reason in enumerate(finish_reasons)
|
||||
],
|
||||
}
|
||||
with pytest.raises(APIError, match="finish_reason=abort") as exc_info:
|
||||
convert_to_model_response_object(
|
||||
response_object=resp,
|
||||
model_response_object=ModelResponse(),
|
||||
response_type="completion",
|
||||
)
|
||||
assert exc_info.value.status_code == 500
|
||||
assert exc_info.value.model == "Qwen/Qwen3-8B"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("choices", "type_name"), [({}, "dict"), ("", "str"), (None, "NoneType"), (0, "int")])
|
||||
@pytest.mark.asyncio
|
||||
async def test_convert_non_list_choices_raises_api_error(choices: object, type_name: str) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue