Repository: vllm-project/guidellm
Issue: KeyError: 'content' when processing streaming chat completions
Root cause: Validation Gap

**Describe the bug**

When running a benchmark against a streaming-capable, OpenAI-compatible chat model, guidellm crashes with a KeyError: 'content'.

This occurs because the final delta chunk sent by the server to signal the end of the stream does not contain a content key, as is standard for the API. The current implementation in guidellm does not handle this case and attempts to access the missing key directly, leading to an unhandled exception.

**Expected behavior**

guidellm should handle the end-of-stream signal gracefully without crashing. It should complete the benchmark and report the results, correctly processing all content-bearing chunks and ignoring the final, content-less chunk.

**Environment**
Include all relevant environment information:
1. OS [e.g. Ubuntu 20.04]: 15.6.1
2. Python version [e.g. 3.12.2]: 3.10.17
3. guidellm version: 0.4.0.dev2

**To Reproduce**
Exact steps to reproduce the behavior:

1. Set up an OpenAI-compatible API endpoint that serves a chat model with streaming enabled. (e.g., using litellm to proxy a model).
2. Set the environment variable to force guidellm to use the chat completions endpoint:
   1     export GUIDELLM__PREFERRED_ROUTE=chat_completions
3. Run the guidellm benchmark command targeting your endpoint. The command will run and appear to work, but will crash just as it is about to finish.

guidellm benchmark run \
  --target "http://your-api-endpoint/v1" \
  --model "your-chat-model" \
  --rate-type "synchronous" \
  --max-requests 1

**Errors**

The following exception is raised at the end of the benchmark run:

    1 Traceback (most recent call last):
    2   File "/path/to/your/guidellm/./.venv/bin/guidellm", line 7, in <module>
    3     sys.exit(cli())
    4   ...
    5   File "/path/to/your/guidellm/src/guidellm/benchmark/entrypoints.py", line 71, in benchmark_generative_text
    6     await backend.validate()
    7   File "/path/to/your/guidellm/src/guidellm/backend/backend.py", line 138, in validate
    8     async for _ in self.chat_completions(  # type: ignore[attr-defined]
    9   File "/path/to/your/guidellm/src/guidellm/backend/openai.py", line 393, in chat_completions
   10     raise ex
   11   File "/path/to/your/guidellm/src/guidellm/backend/openai.py", line 374, in chat_completions
   12     async for resp in self._iterative_completions_request(
   13   File "/path/to/your/guidellm/src/guidellm/backend/openai.py", line 623, in _iterative_completions_request
   14     if delta := self._extract_completions_delta_content(type_, data):
   15   File "/path/to/your/guidellm/src/guidellm/backend/openai.py", line 691, in _extract_completions_delta_content
   16     return data["choices"][0]["delta"]["content"]
   17 KeyError: 'content'

<img width="2014" height="872" alt="Image" src="https://github.com/user-attachments/assets/7fda877e-68a9-4899-8639-6c4c29c1f45d" />

**Additional context**

The issue lies in the _extract_completions_delta_content function within src/guidellm/backend/openai.py. It can be fixed by replacing the direct dictionary access with a safer method like .get() to handle cases where the content key is not present.

Suggested fix:

Change this line:

   1 return data["choices"][0]["delta"]["content"]

  To this:
   1 return data.get("choices", [{}])[0].get("delta", {}).get("content")

This ensures robust handling of the streaming response. A Pull Request with this fix can be submitted.