Skip to content

Commit 0c22a73

Browse files
committed
test: Add test with real chunks and add more chunk metadata
1 parent 3d5d11c commit 0c22a73

2 files changed

Lines changed: 117 additions & 1 deletion

File tree

integrations/watsonx/src/haystack_integrations/components/generators/watsonx/chat/chat_generator.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ def _convert_chunk_to_streaming_chunk(self, chunk: dict[str, Any], component_inf
388388
choice = chunk["choices"][0]
389389
chunk_meta = {
390390
"model": self.model,
391+
"model_id": chunk.get("model_id"),
392+
"model_version": chunk.get("model_version"),
393+
"created": chunk.get("created"),
394+
"created_at": chunk.get("created_at"),
391395
"received_at": datetime.now(timezone.utc).isoformat(),
392396
}
393397

integrations/watsonx/tests/test_chat_generator.py

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pytest
99
from haystack import logging
1010
from haystack.components.generators.utils import print_streaming_chunk
11-
from haystack.dataclasses import ChatMessage, ChatRole, ImageContent, StreamingChunk
11+
from haystack.dataclasses import ChatMessage, ChatRole, ComponentInfo, ImageContent, StreamingChunk
1212
from haystack.tools import Tool, Toolset
1313
from haystack.utils import Secret
1414

@@ -522,6 +522,118 @@ def test_prepare_api_call_image_in_non_user_message(self, mock_watsonx):
522522
with pytest.raises(ValueError, match="Image content is only supported for user messages"):
523523
generator._prepare_api_call(messages=[message])
524524

525+
def test_convert_chunk_to_streaming_chunk_real_example(
526+
self, mock_watsonx: dict[str, AsyncMock | MagicMock]
527+
) -> None:
528+
component = WatsonxChatGenerator(
529+
project_id=Secret.from_token("test-project"), model="meta-llama/llama-3-2-11b-vision-instruct"
530+
)
531+
component_info = ComponentInfo.from_component(component)
532+
533+
# Chunk 1: Text only
534+
chunk1 = {
535+
"id": "chatcmpl-21e72dd9-ed65-49cc-9ea2-64d971707cda---2dedc26eab5af753744ed4eaa116a197---e0399d75-cd8c-486e-b907-dc211cb70eac", # noqa: E501
536+
"object": "chat.completion.chunk",
537+
"model_id": "meta-llama/llama-3-2-11b-vision-instruct",
538+
"model": "meta-llama/llama-3-2-11b-vision-instruct",
539+
"choices": [
540+
{
541+
"index": 0,
542+
"finish_reason": None,
543+
"delta": {"content": "I'll get the weather information for Paris and Berlin"},
544+
}
545+
],
546+
"created": 1773250972,
547+
"model_version": "3.2.0",
548+
"created_at": "2026-03-11T17:42:52.921Z",
549+
}
550+
551+
streaming_chunk1 = component._convert_chunk_to_streaming_chunk(chunk=chunk1, component_info=component_info)
552+
assert streaming_chunk1.content == "I'll get the weather information for Paris and Berlin"
553+
assert streaming_chunk1.tool_calls is None
554+
assert streaming_chunk1.finish_reason is None
555+
assert streaming_chunk1.index == 0
556+
assert "created" in streaming_chunk1.meta
557+
assert "created_at" in streaming_chunk1.meta
558+
assert "received_at" in streaming_chunk1.meta
559+
assert streaming_chunk1.meta["model"] == "meta-llama/llama-3-2-11b-vision-instruct"
560+
assert streaming_chunk1.meta["model_id"] == "meta-llama/llama-3-2-11b-vision-instruct"
561+
assert streaming_chunk1.meta["model_version"] == "3.2.0"
562+
assert streaming_chunk1.component_info == component_info
563+
564+
# Chunk 2: Text only
565+
chunk2 = {
566+
"id": "chatcmpl-21e72dd9-ed65-49cc-9ea2-64d971707cda---2dedc26eab5af753744ed4eaa116a197---e0399d75-cd8c-486e-b907-dc211cb70eac", # noqa: E501
567+
"object": "chat.completion.chunk",
568+
"model_id": "meta-llama/llama-3-2-11b-vision-instruct",
569+
"model": "meta-llama/llama-3-2-11b-vision-instruct",
570+
"choices": [
571+
{"index": 0, "finish_reason": None, "delta": {"content": " and present it in a structured format."}}
572+
],
573+
"created": 1773250972,
574+
"model_version": "3.2.0",
575+
"created_at": "2026-03-11T17:42:52.929Z",
576+
}
577+
578+
streaming_chunk2 = component._convert_chunk_to_streaming_chunk(chunk=chunk2, component_info=component_info)
579+
assert streaming_chunk2.content == " and present it in a structured format."
580+
assert streaming_chunk2.tool_calls is None
581+
assert streaming_chunk2.finish_reason is None
582+
assert streaming_chunk2.index == 0
583+
assert "created" in streaming_chunk2.meta
584+
assert "created_at" in streaming_chunk2.meta
585+
assert "received_at" in streaming_chunk2.meta
586+
assert streaming_chunk2.meta["model"] == "meta-llama/llama-3-2-11b-vision-instruct"
587+
assert streaming_chunk2.meta["model_id"] == "meta-llama/llama-3-2-11b-vision-instruct"
588+
assert streaming_chunk2.meta["model_version"] == "3.2.0"
589+
assert streaming_chunk2.component_info == component_info
590+
591+
# Chunk 3: Multiple tool calls (6 function calls) for 2 cities with 3 tools each
592+
chunk3 = {
593+
"id": "chatcmpl-6b615ca6-4aa7-4f79-832f-bedce4641c2b---87fdc1a1cd2032ff0c6776ecfc20b6a5---34576777-949d-4df1-b95f-56d14b848eca", # noqa: E501
594+
"object": "chat.completion.chunk",
595+
"model_id": "meta-llama/llama-3-2-11b-vision-instruct",
596+
"model": "meta-llama/llama-3-2-11b-vision-instruct",
597+
"choices": [
598+
{
599+
"index": 0,
600+
"finish_reason": None,
601+
"delta": {
602+
"tool_calls": [
603+
{
604+
"index": 0,
605+
"id": "chatcmpl-tool-9646185282a54afc86c3572513b2dafa",
606+
"type": "function",
607+
"function": {"name": "weather", "arguments": ""},
608+
}
609+
]
610+
},
611+
}
612+
],
613+
"created": 1773252289,
614+
"model_version": "3.2.0",
615+
"created_at": "2026-03-11T18:04:49.696Z",
616+
}
617+
618+
streaming_chunk3 = component._convert_chunk_to_streaming_chunk(chunk=chunk3, component_info=component_info)
619+
assert streaming_chunk3.content == ""
620+
assert streaming_chunk3.tool_calls is not None
621+
assert len(streaming_chunk3.tool_calls) == 1
622+
assert streaming_chunk3.finish_reason is None
623+
assert streaming_chunk3.index == 0
624+
assert "created" in streaming_chunk3.meta
625+
assert "created_at" in streaming_chunk3.meta
626+
assert "received_at" in streaming_chunk3.meta
627+
assert streaming_chunk3.meta["model"] == "meta-llama/llama-3-2-11b-vision-instruct"
628+
assert streaming_chunk3.meta["model_id"] == "meta-llama/llama-3-2-11b-vision-instruct"
629+
assert streaming_chunk3.meta["model_version"] == "3.2.0"
630+
assert streaming_chunk3.component_info == component_info
631+
632+
assert streaming_chunk3.tool_calls[0].tool_name == "weather"
633+
assert streaming_chunk3.tool_calls[0].arguments == ""
634+
assert streaming_chunk3.tool_calls[0].id == "chatcmpl-tool-9646185282a54afc86c3572513b2dafa"
635+
assert streaming_chunk3.tool_calls[0].index == 0
636+
525637
def test_multimodal_message_processing(self, mock_watsonx):
526638
"""Test multimodal message processing with mocked model."""
527639
base64_image = (

0 commit comments

Comments
 (0)