Skip to content

Commit da94807

Browse files
Merge branch 'main' into feat/2941-elasticsearch-sparse-embedding-retriever
2 parents 8a65805 + 2d259b9 commit da94807

14 files changed

Lines changed: 1219 additions & 29 deletions

File tree

integrations/ollama/CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Changelog
22

3+
## [integrations/ollama-v6.3.0] - 2026-04-10
4+
5+
### 🐛 Bug Fixes
6+
7+
- Replace in-place dataclass mutations with dataclasses.replace() (#3112)
8+
- Ollama - better reasoning streaming support (#3131)
9+
10+
### 🧪 Testing
11+
12+
- Track test coverage for all integrations (#3065)
13+
14+
### 🧹 Chores
15+
16+
- Add ANN ruff ruleset to llama_cpp, llama_stack, mcp, meta_llama, mistral, mongodb_atlas, nvidia, ollama, openrouter, opensearch (#2991)
17+
- Enforce ruff docstring rules (D102/D103/D205/D209/D213/D417/D419) in integrations 21-30 (#3010)
18+
- Increase lower pins for 3.14 support in some integrations + test with 3.14 (#3033)
19+
20+
321
## [integrations/ollama-v6.2.0] - 2026-03-09
422

523
### 🚀 Features

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,25 @@ def _handle_streaming_response(
376376
id_order: list[str] = []
377377
tool_call_index: int = 0
378378

379+
# track reasoning and content blocks to correctly set start=True on the first chunk of each block
380+
reasoning_started = False
381+
content_started = False
382+
379383
# Stream
380384
for index, raw in enumerate(response_iter):
381385
if raw.message.tool_calls:
382386
tool_call_index += 1
383387
chunk = _build_chunk(
384388
chunk_response=raw, component_info=component_info, index=index, tool_call_index=tool_call_index
385389
)
386-
start = index == 0 or bool(chunk.tool_calls)
390+
391+
if chunk.reasoning:
392+
start = not reasoning_started or bool(chunk.tool_calls)
393+
reasoning_started = True
394+
else:
395+
start = (not content_started) or bool(chunk.tool_calls)
396+
content_started = True
397+
387398
chunk = replace(chunk, start=start)
388399
chunks.append(chunk)
389400

@@ -458,6 +469,10 @@ async def _handle_streaming_response_async(
458469
id_order: list[str] = []
459470
tool_call_index: int = 0
460471

472+
# track reasoning and content blocks to correctly set start=True on the first chunk of each block
473+
reasoning_started = False
474+
content_started = False
475+
461476
# Stream
462477
index = 0
463478
async for raw in response_iter:
@@ -466,7 +481,14 @@ async def _handle_streaming_response_async(
466481
chunk = _build_chunk(
467482
chunk_response=raw, component_info=component_info, index=index, tool_call_index=tool_call_index
468483
)
469-
start = index == 0 or bool(chunk.tool_calls)
484+
485+
if chunk.reasoning:
486+
start = not reasoning_started or bool(chunk.tool_calls)
487+
reasoning_started = True
488+
else:
489+
start = (not content_started) or bool(chunk.tool_calls)
490+
content_started = True
491+
470492
chunk = replace(chunk, start=start)
471493
chunks.append(chunk)
472494

integrations/ollama/tests/test_chat_generator.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,70 @@ def test_callback(chunk: StreamingChunk):
267267
assert streaming_chunks[1].start is False
268268
assert streaming_chunks[2].start is False
269269

270+
def test_handle_streaming_response_with_thinking(self):
271+
ollama_chunks = [
272+
ChatResponse(
273+
model="qwen3:0.6b",
274+
created_at="2025-07-31T15:27:09.265818Z",
275+
done=False,
276+
message=Message(role="assistant", content="", thinking="Let me think"),
277+
),
278+
ChatResponse(
279+
model="qwen3:0.6b",
280+
created_at="2025-07-31T15:27:09.265818Z",
281+
done=False,
282+
message=Message(role="assistant", content="", thinking=" about this."),
283+
),
284+
ChatResponse(
285+
model="qwen3:0.6b",
286+
created_at="2025-07-31T15:27:09.265818Z",
287+
done=False,
288+
message=Message(role="assistant", content="The capital"),
289+
),
290+
ChatResponse(
291+
model="qwen3:0.6b",
292+
created_at="2025-07-31T15:27:09.265818Z",
293+
done=False,
294+
message=Message(role="assistant", content=" is Amman."),
295+
),
296+
ChatResponse(
297+
model="qwen3:0.6b",
298+
created_at="2025-07-31T15:27:09.355211Z",
299+
done=True,
300+
done_reason="stop",
301+
total_duration=1303416458,
302+
load_duration=953922333,
303+
prompt_eval_count=22,
304+
prompt_eval_duration=254166208,
305+
eval_count=3,
306+
eval_duration=92965792,
307+
message=Message(role="assistant", content=""),
308+
),
309+
]
310+
311+
generator = OllamaChatGenerator()
312+
streaming_chunks = []
313+
314+
def test_callback(chunk: StreamingChunk):
315+
streaming_chunks.append(chunk)
316+
317+
response = generator._handle_streaming_response(ollama_chunks, test_callback)
318+
assert response["replies"][0].text == "The capital is Amman."
319+
assert response["replies"][0].reasoning.reasoning_text == "Let me think about this."
320+
321+
assert len(streaming_chunks) == 5
322+
# First reasoning chunk: start=True
323+
assert streaming_chunks[0].start is True
324+
assert streaming_chunks[0].reasoning.reasoning_text == "Let me think"
325+
# Second reasoning chunk: start=False
326+
assert streaming_chunks[1].start is False
327+
# First content chunk after reasoning: start=True
328+
assert streaming_chunks[2].start is True
329+
assert streaming_chunks[2].content == "The capital"
330+
# Remaining content chunks: start=False
331+
assert streaming_chunks[3].start is False
332+
assert streaming_chunks[4].start is False
333+
270334
def test_handle_streaming_response_tool_calls(self):
271335
ollama_chunks = [
272336
ChatResponse(

integrations/opensearch/CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## [integrations/opensearch-v7.2.0] - 2026-04-10
4+
5+
### 🚀 Features
6+
7+
- *(opensearch)* Add support for nested fields in OpenSearchDocumentStore (#3117)
8+
9+
### 🐛 Bug Fixes
10+
11+
- Replace in-place dataclass mutations in document stores (#3114)
12+
13+
### 🧪 Testing
14+
15+
- Better categorize some Document Stores tests (#3085)
16+
17+
318
## [integrations/opensearch-v7.1.0] - 2026-04-01
419

520
### 🚀 Features

0 commit comments

Comments
 (0)