litellm/tests/unit/llms/ollama
Mateo Wang ed9c02d2d9
fix(ollama): one stream id, 400 on non-text tool content, separated tool results, no empty message item (#45177)
* fix(ollama): one stream id, 400 on non-text tool content, separated tool results, no empty message item

The ollama/ text stream minted a fresh chatcmpl- id per chunk; every chunk now carries the one id of its response.
A tool message with int content raised a TypeError inside ollama_pt and answered 500; it now answers 400 naming the
message index and the type it carried. Merged user, tool, and function turns and the text parts of one message were
joined with no separator; they are joined with a newline. A streamed tool call with no text rebuilds to content null
instead of an empty string, and the Responses bridge no longer opens a message item on a leading empty delta, so a
/v1/responses stream on a tool call completes with the function_call alone, as the non-stream call does

* fix(ollama): defer the BadRequestError annotation so litellm imports on Python 3.10 to 3.13

* fix(ollama): read the user run lazily, type the prompt helpers, and 400 on a non-string text part

* fix(ollama): 400 on a text or image_url part that carries no value

* fix(responses): stream bridged output items at contiguous indexes and reject non-object ollama content parts

The chat-completions bridge reserved output_index 0 for the message item, so a
tool-only stream announced its function_call at index 1 with no item at 0 and the
OpenAI SDK's responses.stream() accumulator raised IndexError. Items now take the
next index in emission order, reasoning included, and response.completed lists
the output in that streamed order.

ollama_pt answers 400 for a content part that is not an object and for an
image_url object without a url string, instead of a 500 or a silent drop.

* fix(responses): list only announced items in the bridged completed snapshot

The Responses bridge drops a message item from response.completed when the
stream never announced one and its text is empty, so a tool-only stream and a
reasoning-only stream end with the items the client saw. The chunk builder's
rebuilt content goes back to what main does; aligning it with the non-stream
shape is its own change for every provider's consumers

* style(responses): sort the itertools import with the other stdlib imports

* test(integration): add ollama prompt-tools and responses bridge audit cells
2026-10-07 19:08:26 -07:00
..
__init__.py test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00
test_ollama_chat_transformation.py test: move the unit half of 126 mixed legacy files into tests/unit (#45090) 2026-10-07 14:07:43 -07:00
test_ollama_completion_transformation.py fix(ollama): one stream id, 400 on non-text tool content, separated tool results, no empty message item (#45177) 2026-10-07 19:08:26 -07:00
test_ollama_embedding.py test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00
test_ollama_model_info.py test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00