ollama-haystack 2.4.2__tar.gz → 3.0.0__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 (22) hide show
  1. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/CHANGELOG.md +7 -0
  2. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/PKG-INFO +2 -2
  3. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/pyproject.toml +1 -1
  4. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/generators/ollama/chat/chat_generator.py +1 -8
  5. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/generators/ollama/generator.py +73 -3
  6. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/tests/test_chat_generator.py +2 -1
  7. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/.gitignore +0 -0
  8. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/LICENSE.txt +0 -0
  9. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/README.md +0 -0
  10. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/examples/chat_generator_example.py +0 -0
  11. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/examples/embedders_example.py +0 -0
  12. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/examples/generator_example.py +0 -0
  13. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/pydoc/config.yml +0 -0
  14. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/embedders/ollama/__init__.py +0 -0
  15. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/embedders/ollama/document_embedder.py +0 -0
  16. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/embedders/ollama/text_embedder.py +0 -0
  17. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/generators/ollama/__init__.py +0 -0
  18. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/src/haystack_integrations/components/generators/ollama/chat/__init__.py +0 -0
  19. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/tests/__init__.py +0 -0
  20. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/tests/test_document_embedder.py +0 -0
  21. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/tests/test_generator.py +0 -0
  22. {ollama_haystack-2.4.2 → ollama_haystack-3.0.0}/tests/test_text_embedder.py +0 -0
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/ollama-v2.4.2] - 2025-05-07
4
+
5
+ ### 🐛 Bug Fixes
6
+
7
+ - Ollama streaming metadata 1686 (#1698)
8
+
9
+
3
10
  ## [integrations/ollama-v2.4.1] - 2025-04-10
4
11
 
5
12
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ollama-haystack
3
- Version: 2.4.2
3
+ Version: 3.0.0
4
4
  Summary: An integration between the Ollama LLM framework and Haystack
5
5
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/ollama#readme
6
6
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
19
19
  Classifier: Programming Language :: Python :: Implementation :: CPython
20
20
  Classifier: Programming Language :: Python :: Implementation :: PyPy
21
21
  Requires-Python: >=3.9
22
- Requires-Dist: haystack-ai
22
+ Requires-Dist: haystack-ai>=2.13.1
23
23
  Requires-Dist: ollama>=0.4.0
24
24
  Requires-Dist: pydantic
25
25
  Description-Content-Type: text/markdown
@@ -27,7 +27,7 @@ classifiers = [
27
27
  "Programming Language :: Python :: Implementation :: CPython",
28
28
  "Programming Language :: Python :: Implementation :: PyPy",
29
29
  ]
30
- dependencies = ["haystack-ai", "ollama>=0.4.0", "pydantic"]
30
+ dependencies = ["haystack-ai>=2.13.1", "ollama>=0.4.0", "pydantic"]
31
31
 
32
32
  [project.urls]
33
33
  Documentation = "https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/ollama#readme"
@@ -2,15 +2,8 @@ from typing import Any, Callable, Dict, List, Literal, Optional, Union
2
2
 
3
3
  from haystack import component, default_from_dict, default_to_dict
4
4
  from haystack.dataclasses import ChatMessage, StreamingChunk, ToolCall
5
- from haystack.tools import Tool, _check_duplicate_tool_names
5
+ from haystack.tools import Tool, _check_duplicate_tool_names, deserialize_tools_or_toolset_inplace
6
6
  from haystack.utils.callable_serialization import deserialize_callable, serialize_callable
7
-
8
- # Compatibility with Haystack 2.12.0 and 2.13.0 - remove after 2.13.0 is released
9
- try:
10
- from haystack.tools import deserialize_tools_or_toolset_inplace
11
- except ImportError:
12
- from haystack.tools import deserialize_tools_inplace as deserialize_tools_or_toolset_inplace
13
-
14
7
  from pydantic.json_schema import JsonSchemaValue
15
8
 
16
9
  from ollama import ChatResponse, Client
@@ -7,6 +7,73 @@ from haystack.utils.callable_serialization import deserialize_callable, serializ
7
7
  from ollama import Client, GenerateResponse
8
8
 
9
9
 
10
+ def _convert_ollama_meta_to_openai_format(intput_response_dict: Dict) -> Dict:
11
+ """
12
+ Converts Ollama metadata format to OpenAI-metadata format for standardization.
13
+
14
+ The conversion follows these mapping rules:
15
+ - 'done_reason' -> 'finish_reason'
16
+ - 'created_at' -> 'completion_start_time'
17
+ - 'eval_count' and 'prompt_eval_count' -> 'usage' dict with token counts
18
+ - All other fields are preserved as-is except 'response'.
19
+
20
+ Input Ollama-metadata format example:
21
+ {
22
+ 'model': 'llama3.2:3b',
23
+ 'created_at': '2025-05-15T14:11:57.8920338Z',
24
+ 'done': True,
25
+ 'done_reason': 'stop',
26
+ 'total_duration': 871519900,
27
+ 'load_duration': 44376100,
28
+ 'prompt_eval_count': 29,
29
+ 'prompt_eval_duration': 380700800,
30
+ 'eval_count': 8,
31
+ 'eval_duration': 445131300,
32
+ 'context': [28006,
33
+ 9125,
34
+ ...
35
+ 220,
36
+ 18]
37
+ }
38
+
39
+ Returned OpenAI-metadata format example:
40
+ {
41
+ 'model': 'llama3.2:3b',
42
+ 'finish_reason': 'stop',
43
+ 'usage': {
44
+ 'completion_tokens': 8,
45
+ 'prompt_tokens': 29,
46
+ 'total_tokens': 37,
47
+ }
48
+ 'created_at': '2025-05-15T14:11:57.8920338Z',
49
+ 'done': True,
50
+ 'total_duration': 871519900,
51
+ 'load_duration': 44376100,
52
+ 'prompt_eval_duration': 380700800,
53
+ 'eval_duration': 445131300,
54
+ 'context': [28006,
55
+ 9125,
56
+ ...
57
+ 220,
58
+ 18]
59
+ }
60
+ """
61
+
62
+ meta = {key: value for key, value in intput_response_dict.items() if key != "response"}
63
+
64
+ if "done_reason" in meta:
65
+ meta["finish_reason"] = meta.pop("done_reason")
66
+ if "eval_count" in meta and "prompt_eval_count" in meta:
67
+ eval_count = meta.pop("eval_count")
68
+ prompt_eval_count = meta.pop("prompt_eval_count")
69
+ meta["usage"] = {
70
+ "completion_tokens": eval_count,
71
+ "prompt_tokens": prompt_eval_count,
72
+ "total_tokens": eval_count + prompt_eval_count,
73
+ }
74
+ return meta
75
+
76
+
10
77
  @component
11
78
  class OllamaGenerator:
12
79
  """
@@ -122,8 +189,9 @@ class OllamaGenerator:
122
189
  """
123
190
  Converts a response from the Ollama API to the required Haystack format.
124
191
  """
125
- reply = ollama_response.response
126
- meta = {key: value for key, value in ollama_response.model_dump().items() if key != "response"}
192
+ response_dict = ollama_response.model_dump()
193
+ reply = response_dict["response"]
194
+ meta = _convert_ollama_meta_to_openai_format(response_dict)
127
195
 
128
196
  return {"replies": [reply], "meta": [meta]}
129
197
 
@@ -133,7 +201,9 @@ class OllamaGenerator:
133
201
  """
134
202
 
135
203
  replies = ["".join([c.content for c in chunks])]
136
- meta = {key: value for key, value in chunks[0].meta.items() if key != "response"}
204
+
205
+ # Convert the metadata from the last chunk
206
+ meta = _convert_ollama_meta_to_openai_format(chunks[-1].meta)
137
207
 
138
208
  return {"replies": replies, "meta": [meta]}
139
209
 
@@ -574,10 +574,11 @@ class TestOllamaChatGenerator:
574
574
  response_format = {
575
575
  "type": "object",
576
576
  "properties": {"capital": {"type": "string"}, "population": {"type": "number"}},
577
+ "required": ["capital", "population"],
577
578
  }
578
579
  chat_generator = OllamaChatGenerator(model="llama3.2:3b", response_format=response_format)
579
580
 
580
- message = ChatMessage.from_user("What's the capital of France and its population?")
581
+ message = ChatMessage.from_user("What's the capital of France and its population? Respond in JSON format.")
581
582
  response = chat_generator.run([message])
582
583
 
583
584
  assert isinstance(response, dict)