Skip to content

Commit dab83c2

Browse files
author
ebarkhordar
committed
fix(sambanova): emit empty delta on usage-only final stream chunk
SambaNovaCloud enables stream_options={'include_usage': True} by default, so the stream ends with a usage-only chunk where choices == []. That chunk takes the else branch, which never reassigns content_delta, so the final yield re-emits the previous chunk's token as its delta. This breaks the streaming invariant that ''.join(deltas) equals the final message.content. Set content_delta to '' on the usage-only chunk. Adds a regression test that stubs the streaming request and asserts the concatenated deltas equal the final content.
1 parent 67514f6 commit dab83c2

4 files changed

Lines changed: 35 additions & 2 deletions

File tree

llama-index-integrations/llms/llama-index-llms-sambanovasystems/llama_index/llms/sambanovasystems/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,10 @@ def stream_chat(
551551
),
552552
}
553553
else:
554+
# A usage-only / final chunk has choices == [] and carries no new
555+
# text, so its delta must be empty; otherwise the previous chunk's
556+
# content_delta is re-emitted and "".join(deltas) != message.content.
557+
content_delta = ""
554558
additional_kwargs = {
555559
"id": partial_response["id"],
556560
"finish_reason": finish_reason,

llama-index-integrations/llms/llama-index-llms-sambanovasystems/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ dev = [
2626

2727
[project]
2828
name = "llama-index-llms-sambanovasystems"
29-
version = "0.6.0"
29+
version = "0.6.1"
3030
description = "llama-index llms sambanova cloud and sambastudio integration"
3131
authors = [{name = "Rodrigo Maldonado", email = "rodrigo.maldonado@pucp.edu.pe"}]
3232
requires-python = ">=3.10,<4.0"

llama-index-integrations/llms/llama-index-llms-sambanovasystems/tests/test_llms_sambanovasystems.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,35 @@ def test_init():
214214
_ = SambaStudio(sambastudio_url="fake/stream/url", sambastudio_api_key="fake")
215215

216216

217+
def test_stream_chat_usage_chunk_emits_empty_delta():
218+
"""Usage-only final chunk (choices == []) must yield an empty delta so concatenated deltas equal the final content."""
219+
client = SambaNovaCloud(sambanova_api_key="fake")
220+
221+
def fake_streaming_request(messages_dicts, stop=None):
222+
yield {
223+
"id": "id-0",
224+
"choices": [{"delta": {"content": "Hello"}, "finish_reason": None}],
225+
}
226+
# include_usage=True (the default) appends a trailing usage-only chunk
227+
yield {
228+
"id": "id-0",
229+
"choices": [],
230+
"usage": {"total_tokens": 5},
231+
"model": "Meta-Llama-3.1-8B-Instruct",
232+
"system_fingerprint": "fp",
233+
"created": 1,
234+
}
235+
236+
client._handle_streaming_request = fake_streaming_request
237+
238+
messages = [ChatMessage(role=MessageRole.USER, content="hi")]
239+
responses = list(client.stream_chat(messages))
240+
241+
joined_deltas = "".join(r.delta for r in responses)
242+
assert joined_deltas == responses[-1].message.content == "Hello"
243+
assert responses[-1].delta == ""
244+
245+
217246
if __name__ == "__main__":
218247
test_sambanovacloud()
219248
test_sambastudio()

llama-index-integrations/llms/llama-index-llms-sambanovasystems/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)