cohere-haystack 9.3.0__tar.gz → 9.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/CHANGELOG.md +19 -0
  2. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/PKG-INFO +1 -1
  3. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/generators/cohere/chat/chat_generator.py +25 -2
  4. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_chat_generator_chunks.py +62 -0
  5. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/.gitignore +0 -0
  6. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/LICENSE.txt +0 -0
  7. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/README.md +0 -0
  8. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/examples/cohere_embedding.py +0 -0
  9. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/examples/cohere_generation.py +0 -0
  10. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/examples/cohere_ranker.py +0 -0
  11. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/pydoc/config_docusaurus.yml +0 -0
  12. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/pyproject.toml +0 -0
  13. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/cohere/__init__.py +0 -0
  14. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/cohere/document_embedder.py +0 -0
  15. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/cohere/document_image_embedder.py +0 -0
  16. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/cohere/embedding_types.py +0 -0
  17. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/cohere/text_embedder.py +0 -0
  18. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/cohere/utils.py +0 -0
  19. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/embedders/py.typed +0 -0
  20. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/generators/cohere/__init__.py +0 -0
  21. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/generators/cohere/chat/__init__.py +0 -0
  22. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/generators/cohere/generator.py +0 -0
  23. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/generators/py.typed +0 -0
  24. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/rankers/cohere/__init__.py +0 -0
  25. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/rankers/cohere/ranker.py +0 -0
  26. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/src/haystack_integrations/components/rankers/py.typed +0 -0
  27. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/__init__.py +0 -0
  28. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/conftest.py +0 -0
  29. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_chat_generator.py +0 -0
  30. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_chat_generator_async.py +0 -0
  31. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_document_embedder.py +0 -0
  32. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_document_image_embedder.py +0 -0
  33. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_files/apple.jpg +0 -0
  34. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_files/sample_pdf_1.pdf +0 -0
  35. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_generator.py +0 -0
  36. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_ranker.py +0 -0
  37. {cohere_haystack-9.3.0 → cohere_haystack-9.4.1}/tests/test_text_embedder.py +0 -0
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/cohere-v9.4.0] - 2026-07-22
4
+
5
+ ### 🐛 Bug Fixes
6
+
7
+ - *(cohere)* Include citations in streaming ChatMessage meta (#3580)
8
+
9
+
10
+ ## [integrations/cohere-v9.3.0] - 2026-07-09
11
+
12
+ ### 🧪 Testing
13
+
14
+ - Guard ToolInvoker imports so chat-generator tests run under Haystack 3.0 (#3535)
15
+ - Fix cohere, amazon_bedrock, mirage, and ollama tests under Haystack 3.0 (#3566)
16
+
17
+ ### 🧹 Chores
18
+
19
+ - Support sync streaming callbacks in async contexts for Haystack 2.x/3.x compatibility (#3534)
20
+
21
+
3
22
  ## [integrations/cohere-v9.2.0] - 2026-06-05
4
23
 
5
24
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cohere-haystack
3
- Version: 9.3.0
3
+ Version: 9.4.1
4
4
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/cohere#readme
5
5
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
6
6
  Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/cohere
@@ -275,6 +275,17 @@ def _convert_cohere_chunk_to_streaming_chunk(
275
275
  arguments = chunk.delta.message.tool_calls.function.arguments
276
276
  tool_calls = [ToolCallDelta(index=global_index, arguments=arguments)]
277
277
 
278
+ elif chunk.type == "citation-start":
279
+ # Each citation-start chunk carries one Citation object in delta.message.citations.
280
+ # Collect it here so _parse_streaming_response can aggregate them into the final message
281
+ # meta, matching the behavior of the non-streaming path which returns citations via
282
+ # chat_response.message.citations.
283
+ delta = getattr(chunk, "delta", None)
284
+ if delta and delta.message:
285
+ citation = getattr(delta.message, "citations", None)
286
+ if citation is not None:
287
+ meta["citations"] = [citation]
288
+
278
289
  elif chunk.type == "message-end":
279
290
  finish_reason_raw = getattr(chunk.delta, "finish_reason", None)
280
291
  finish_reason = FINISH_REASON_MAPPING.get(finish_reason_raw) if finish_reason_raw else None
@@ -345,7 +356,14 @@ def _parse_streaming_response(
345
356
  chunks.append(streaming_chunk)
346
357
  streaming_callback(streaming_chunk)
347
358
 
348
- return _convert_streaming_chunks_to_chat_message(chunks=chunks)
359
+ message = _convert_streaming_chunks_to_chat_message(chunks=chunks)
360
+
361
+ # Aggregate citations collected from citation-start chunks into the message meta,
362
+ # mirroring the non-streaming path which sets meta["citations"] from chat_response.message.citations.
363
+ citations = [c for sc in chunks for c in (sc.meta.get("citations") or [])]
364
+ message.meta["citations"] = citations if citations else None
365
+
366
+ return message
349
367
 
350
368
 
351
369
  async def _parse_async_streaming_response(
@@ -380,7 +398,12 @@ async def _parse_async_streaming_response(
380
398
  if inspect.isawaitable(callback_result):
381
399
  await callback_result
382
400
 
383
- return _convert_streaming_chunks_to_chat_message(chunks=chunks)
401
+ message = _convert_streaming_chunks_to_chat_message(chunks=chunks)
402
+
403
+ citations = [c for sc in chunks for c in (sc.meta.get("citations") or [])]
404
+ message.meta["citations"] = citations if citations else None
405
+
406
+ return message
384
407
 
385
408
 
386
409
  @component
@@ -358,6 +358,7 @@ class TestCohereChunkConversion:
358
358
  "finish_reason": "tool_calls",
359
359
  "index": 0,
360
360
  "usage": {"prompt_tokens": 60.0, "completion_tokens": 41.0},
361
+ "citations": None,
361
362
  },
362
363
  )
363
364
 
@@ -406,3 +407,64 @@ class TestCohereChunkConversion:
406
407
  result = _convert_cohere_chunk_to_streaming_chunk(chunk=mock_chunk, model="command-r-08-2024")
407
408
 
408
409
  assert result.meta["usage"] == {"completion_tokens": 0.0, "prompt_tokens": 0.0}
410
+
411
+ def test_convert_citation_start_chunk(self):
412
+ citation = MagicMock()
413
+ citation.start = 0
414
+ citation.end = 10
415
+ citation.text = "Hello world"
416
+
417
+ delta_message = MagicMock()
418
+ delta_message.citations = citation
419
+
420
+ delta = MagicMock()
421
+ delta.message = delta_message
422
+
423
+ mock_chunk = MagicMock()
424
+ mock_chunk.type = "citation-start"
425
+ mock_chunk.delta = delta
426
+
427
+ result = _convert_cohere_chunk_to_streaming_chunk(chunk=mock_chunk, model="command-r-08-2024")
428
+
429
+ assert result.content == ""
430
+ assert result.start is False
431
+ assert result.tool_calls is None
432
+ assert result.finish_reason is None
433
+ assert result.meta["citations"] == [citation]
434
+
435
+ def test_parse_streaming_response_with_citations(self):
436
+ citation = MagicMock()
437
+ citation.start = 0
438
+ citation.end = 5
439
+ citation.text = "Hello"
440
+
441
+ delta_message = MagicMock()
442
+ delta_message.citations = citation
443
+
444
+ delta = MagicMock()
445
+ delta.message = delta_message
446
+
447
+ citation_chunk = MagicMock()
448
+ citation_chunk.type = "citation-start"
449
+ citation_chunk.delta = delta
450
+
451
+ msg_end_chunk = MsgEndStream(
452
+ type="message-end",
453
+ delta=MsgEndDelta(
454
+ finish_reason="COMPLETE",
455
+ usage=Usage(
456
+ billed_units=BilledUnits(input_tokens=5.0, output_tokens=5.0),
457
+ tokens=UsageTokens(input_tokens=50.0, output_tokens=20.0),
458
+ ),
459
+ ),
460
+ )
461
+
462
+ stream = iter([citation_chunk, msg_end_chunk])
463
+ chat_message = _parse_streaming_response(
464
+ stream,
465
+ model="command-r-08-2024",
466
+ streaming_callback=lambda _: None,
467
+ component_info=ComponentInfo(type="type"),
468
+ )
469
+
470
+ assert chat_message.meta["citations"] == [citation]