Both the OpenAI and DeepSeek providers read response.choices[0].message.content without checking that choices is non-empty:
keep/providers/openai_provider/openai_provider.py:69
keep/providers/deepseek_provider/deepseek_provider.py:83
An OpenAI-compatible backend can return HTTP 200 with an empty choices list, for example when a content filter blocks the completion. choices[0] then raises IndexError and the workflow step fails instead of degrading.
This is the same failure fixed for litellm/vllm in #6705 and for grok in #6710; these two providers were not covered.
Reproduction
Call _query with a client whose response has choices == []:
IndexError: list index out of range
Expected
Return an empty string, the way grok/litellm/vllm now do, so an empty completion does not crash the step.
Both the OpenAI and DeepSeek providers read
response.choices[0].message.contentwithout checking thatchoicesis non-empty:keep/providers/openai_provider/openai_provider.py:69keep/providers/deepseek_provider/deepseek_provider.py:83An OpenAI-compatible backend can return HTTP 200 with an empty
choiceslist, for example when a content filter blocks the completion.choices[0]then raisesIndexErrorand the workflow step fails instead of degrading.This is the same failure fixed for litellm/vllm in #6705 and for grok in #6710; these two providers were not covered.
Reproduction
Call
_querywith a client whose response haschoices == []:Expected
Return an empty string, the way grok/litellm/vllm now do, so an empty completion does not crash the step.