fix(ollama): reasoning should come before text content (#32476)

This commit is contained in:
Mason Daugherty 2025-08-08 19:34:36 -04:00 committed by GitHub
parent 7f989d3c3b
commit 13d67cf37e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 6 deletions

View File

@ -181,12 +181,6 @@ def _convert_to_v1_from_ollama_format(response: dict[str, Any]) -> AIMessage:
"""Convert Ollama API response to AIMessage."""
content: list[types.ContentBlock] = []
# Handle text content
if "message" in response and "content" in response["message"]:
text_content = response["message"]["content"]
if text_content:
content.append(TextContentBlock(type="text", text=text_content))
# Handle reasoning content first (should come before main response)
if "message" in response and "thinking" in response["message"]:
thinking_content = response["message"]["thinking"]
@ -198,6 +192,12 @@ def _convert_to_v1_from_ollama_format(response: dict[str, Any]) -> AIMessage:
)
)
# Handle text content
if "message" in response and "content" in response["message"]:
text_content = response["message"]["content"]
if text_content:
content.append(TextContentBlock(type="text", text=text_content))
# Handle tool calls
if "message" in response and "tool_calls" in response["message"]:
tool_calls = response["message"]["tool_calls"]

View File

@ -185,6 +185,50 @@ class TestMessageConversion:
assert result.content[0].get("text") == "Hello"
assert result.response_metadata.get("context") == test_context
def test_reasoning_content_block_comes_before_text(self) -> None:
"""Test that ReasoningContentBlock always comes before TextContentBlock."""
ollama_response = {
"model": MODEL_NAME,
"created_at": "2024-01-01T00:00:00Z",
"message": {
"role": "assistant",
"content": "The final answer is 4.",
"thinking": "Let me calculate: 2 + 2 = 4",
},
"done": True,
"done_reason": "stop",
}
result = _convert_to_v1_from_ollama_format(ollama_response)
assert isinstance(result, AIMessage)
assert len(result.content) == 2
assert result.content[0].get("type") == "reasoning"
assert result.content[1].get("type") == "text"
def test_reasoning_content_block_comes_before_text_in_chunks(self) -> None:
"""Test ReasoningContentBlock comes before TextContentBlock in chunks."""
chunk = {
"model": MODEL_NAME,
"created_at": "2024-01-01T00:00:00Z",
"message": {
"role": "assistant",
"content": "The answer is 42.",
"thinking": "I need to think about this carefully...",
},
"done": False,
}
result = _convert_chunk_to_v1(chunk)
assert len(result.content) == 2
assert result.content[0].get("type") == "reasoning"
reasoning_text = "I need to think about this carefully..."
assert result.content[0].get("reasoning") == reasoning_text
assert result.content[1].get("type") == "text"
assert result.content[1].get("text") == "The answer is 42."
def test_convert_empty_content(self) -> None:
"""Test converting empty content blocks."""
message = HumanMessage(content=[])