Co-authored-by: Quentin Torroba <quentin.torroba@mistral.ai>
Co-authored-by: Clement Sirieix <clem.sirieix@gmail.com>
Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai>
Co-authored-by: Simon Van de Kerckhove <simon.vandekerckhove@mistral.ai>
Co-authored-by: Vincent Guilloux <vincent.guilloux@mistral.ai>
Co-authored-by: Michel Thomazo <michel.thomazo@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Mathias Gesbert 2026-03-16 17:51:47 +01:00 committed by GitHub
parent 9421fbc08e
commit 5103019b01
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
104 changed files with 7277 additions and 691 deletions

View file

@ -3,7 +3,12 @@ from __future__ import annotations
from unittest.mock import MagicMock
import httpx
import mistralai
from mistralai.client.models import (
AssistantMessage,
ContentChunk,
TextChunk,
ThinkChunk,
)
import pytest
import respx
@ -38,8 +43,8 @@ class TestMistralMapperParseContent:
def test_parse_content_text_chunk_returns_content_only(self):
mapper = MistralMapper()
content: list[mistralai.ContentChunk] = [
mistralai.TextChunk(type="text", text="Hello from text chunk")
content: list[ContentChunk] = [
TextChunk(type="text", text="Hello from text chunk")
]
result = mapper.parse_content(content)
@ -50,12 +55,12 @@ class TestMistralMapperParseContent:
def test_parse_content_thinking_chunk_extracts_reasoning(self):
mapper = MistralMapper()
content: list[mistralai.ContentChunk] = [
mistralai.ThinkChunk(
content: list[ContentChunk] = [
ThinkChunk(
type="thinking",
thinking=[mistralai.TextChunk(type="text", text="Let me think...")],
thinking=[TextChunk(type="text", text="Let me think...")],
),
mistralai.TextChunk(type="text", text="The answer is 42."),
TextChunk(type="text", text="The answer is 42."),
]
result = mapper.parse_content(content)
@ -66,16 +71,16 @@ class TestMistralMapperParseContent:
def test_parse_content_multiple_thinking_chunks_concatenates(self):
mapper = MistralMapper()
content: list[mistralai.ContentChunk] = [
mistralai.ThinkChunk(
content: list[ContentChunk] = [
ThinkChunk(
type="thinking",
thinking=[mistralai.TextChunk(type="text", text="First thought. ")],
thinking=[TextChunk(type="text", text="First thought. ")],
),
mistralai.ThinkChunk(
ThinkChunk(
type="thinking",
thinking=[mistralai.TextChunk(type="text", text="Second thought.")],
thinking=[TextChunk(type="text", text="Second thought.")],
),
mistralai.TextChunk(type="text", text="Final answer."),
TextChunk(type="text", text="Final answer."),
]
result = mapper.parse_content(content)
@ -86,10 +91,10 @@ class TestMistralMapperParseContent:
def test_parse_content_thinking_only_returns_empty_content(self):
mapper = MistralMapper()
content: list[mistralai.ContentChunk] = [
mistralai.ThinkChunk(
content: list[ContentChunk] = [
ThinkChunk(
type="thinking",
thinking=[mistralai.TextChunk(type="text", text="Just thinking...")],
thinking=[TextChunk(type="text", text="Just thinking...")],
)
]
@ -99,7 +104,7 @@ class TestMistralMapperParseContent:
def test_parse_content_empty_list_returns_empty(self):
mapper = MistralMapper()
content: list[mistralai.ContentChunk] = []
content: list[ContentChunk] = []
result = mapper.parse_content(content)
@ -113,7 +118,7 @@ class TestMistralMapperPrepareMessage:
result = mapper.prepare_message(msg)
assert isinstance(result, mistralai.AssistantMessage)
assert isinstance(result, AssistantMessage)
assert result.content == "Hello!"
def test_prepare_assistant_message_with_reasoning_creates_chunks(self):
@ -126,20 +131,20 @@ class TestMistralMapperPrepareMessage:
result = mapper.prepare_message(msg)
assert isinstance(result, mistralai.AssistantMessage)
assert isinstance(result, AssistantMessage)
assert isinstance(result.content, list)
assert len(result.content) == 2
think_chunk = result.content[0]
assert isinstance(think_chunk, mistralai.ThinkChunk)
assert isinstance(think_chunk, ThinkChunk)
assert think_chunk.type == "thinking"
assert len(think_chunk.thinking) == 1
inner_chunk = think_chunk.thinking[0]
assert isinstance(inner_chunk, mistralai.TextChunk)
assert isinstance(inner_chunk, TextChunk)
assert inner_chunk.text == "Let me calculate..."
text_chunk = result.content[1]
assert isinstance(text_chunk, mistralai.TextChunk)
assert isinstance(text_chunk, TextChunk)
assert text_chunk.type == "text"
assert text_chunk.text == "The answer is 42."
@ -151,20 +156,20 @@ class TestMistralMapperPrepareMessage:
result = mapper.prepare_message(msg)
assert isinstance(result, mistralai.AssistantMessage)
assert isinstance(result, AssistantMessage)
assert isinstance(result.content, list)
assert len(result.content) == 2
think_chunk = result.content[0]
assert isinstance(think_chunk, mistralai.ThinkChunk)
assert isinstance(think_chunk, ThinkChunk)
assert think_chunk.type == "thinking"
assert len(think_chunk.thinking) == 1
inner_chunk = think_chunk.thinking[0]
assert isinstance(inner_chunk, mistralai.TextChunk)
assert isinstance(inner_chunk, TextChunk)
assert inner_chunk.text == "Just thinking..."
text_chunk = result.content[1]
assert isinstance(text_chunk, mistralai.TextChunk)
assert isinstance(text_chunk, TextChunk)
assert text_chunk.text == ""