OpenAI streaming with include_usage=True emits a final usage chunk
with choices=[]. check_streaming_response() assumed every chunk has
at least one choice and crashed with IndexError on chunk.choices[0].
Add an early-continue guard to skip usage-only chunks.
The Azure streaming fix (PR #25638) made is_chunk_non_empty() treat
any first chunk with role!=None as non-empty, for all providers. This
broke OpenAI/Mistral tests where the role-only first chunk was expected
to be filtered, and test idx==0 assumed the first emitted chunk had
actual content (tool_calls, logprobs, etc.).
Restrict the condition to Azure, which is the provider that actually
needs it: Azure sends prompt_filter_results before the first content
chunk, which consumes sent_first_chunk and strips role from the real
first chunk. Other providers should retain the original behavior.
When logprobs are requested, OpenAI's first streaming chunk has
role='assistant' and logprobs=ChoiceLogprobs(content=[]). The Azure
streaming fix (PR #25638) made is_chunk_non_empty() treat any first
chunk with a non-None role as non-empty, which caused this role-only
chunk to be emitted. Callers checking 'logprobs in chunk.choices[0]'
then crashed on logprobs.content[0] (IndexError: list index out of range).
Guard the role condition: don't emit the first chunk as non-empty when
logprobs is present but has no content entries. Azure's use case (no
logprobs, empty choices[]) is unaffected.
The blog CSS selectors for dark mode used descendant selectors like
[data-theme='dark'] .blog-wrapper which never matched because both
data-theme and .blog-wrapper are applied to the same <html> element
by Docusaurus. Fixed by using compound selectors (no space):
[data-theme='dark'].blog-wrapper.
Also added missing dark-mode overrides for:
- pre/code blocks in blog posts
- link colors in blog posts
- marquee items, separators, and labels on blog list page
- pagination links on blog list page
- meta text and author separators on blog list page
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Krrish Dholakia <krrish-berri-2@users.noreply.github.com>
When Azure sends stream_options.include_usage=True, it emits an initial
chunk with choices=[] (prompt_filter_results) before the first content
chunk. Previously, LiteLLM inflated this empty-choices chunk with a
default StreamingChoices, which consumed the sent_first_chunk flag and
caused strip_role_from_delta to strip role from the real first chunk.
Additionally, the first real chunk with role='assistant' and content=''
was discarded by is_chunk_non_empty as "empty".
This fix:
- Forwards chunks with choices=[] faithfully (no inflated default)
- Only marks sent_first_chunk for chunks with real choices
- Treats chunks with role in delta as non-empty
- Guards choices[0] access in __next__/__anext__ and stream_chunk_builder
Fixes#24221
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Avoid module-level cyclic import between llm_passthrough_endpoints and
pass_through_endpoints; CodeQL and partial init order no longer risk
undefined LITELLM_PASS_THROUGH_CUSTOM_BODY_STATE_KEY.
Made-with: Cursor