WIP: PAIN

This commit is contained in:
2026-03-05 14:24:03 -05:00
parent e81843b11b
commit 0e3b479bd6
27 changed files with 684 additions and 772 deletions

View File

@@ -1,5 +1,7 @@
from unittest.mock import patch, MagicMock
import ai_client
from src import ai_client
import json
import pytest
def test_deepseek_model_selection() -> None:
"""
@@ -9,117 +11,104 @@ def test_deepseek_model_selection() -> None:
assert ai_client._provider == "deepseek"
assert ai_client._model == "deepseek-chat"
def test_deepseek_completion_logic() -> None:
@patch("requests.post")
def test_deepseek_completion_logic(mock_post: MagicMock) -> None:
"""
Verifies that ai_client.send() correctly calls the DeepSeek API and returns content.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
with patch("requests.post") as mock_post:
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"choices": [{
"message": {"role": "assistant", "content": "DeepSeek Response"},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 10, "completion_tokens": 5}
"choices": [{"message": {"content": "Hello World"}, "finish_reason": "stop"}]
}
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Hello", base_dir=".")
assert result == "DeepSeek Response"
result = ai_client.send(md_content="Context", user_message="Hi", base_dir=".")
assert result == "Hello World"
assert mock_post.called
def test_deepseek_reasoning_logic() -> None:
@patch("requests.post")
def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None:
"""
Verifies that reasoning_content is captured and wrapped in <thinking> tags.
"""
ai_client.set_provider("deepseek", "deepseek-reasoner")
with patch("requests.post") as mock_post:
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"choices": [{
"message": {
"role": "assistant",
"content": "Final Answer",
"reasoning_content": "Chain of thought"
},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 10, "completion_tokens": 20}
"message": {"content": "Final answer", "reasoning_content": "Chain of thought"},
"finish_reason": "stop"
}]
}
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Reasoning test", base_dir=".")
result = ai_client.send(md_content="Context", user_message="Hi", base_dir=".")
assert "<thinking>\nChain of thought\n</thinking>" in result
assert "Final Answer" in result
assert "Final answer" in result
def test_deepseek_tool_calling() -> None:
@patch("requests.post")
def test_deepseek_tool_calling(mock_post: MagicMock) -> None:
"""
Verifies that DeepSeek provider correctly identifies and executes tool calls.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
with patch("requests.post") as mock_post, \
patch("mcp_client.dispatch") as mock_dispatch:
# 1. Mock first response with a tool call
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}), \
patch("src.mcp_client.dispatch") as mock_dispatch:
# Round 1: Model calls a tool
mock_resp1 = MagicMock()
mock_resp1.status_code = 200
mock_resp1.json.return_value = {
"choices": [{
"message": {
"role": "assistant",
"content": "Let me read that file.",
"tool_calls": [{
"id": "call_123",
"type": "function",
"function": {
"name": "read_file",
"arguments": '{"path": "test.txt"}'
}
}]
},
"finish_reason": "tool_calls"
}],
"usage": {"prompt_tokens": 50, "completion_tokens": 10}
"message": {
"content": "I will read the file",
"tool_calls": [{
"id": "call_1",
"type": "function",
"function": {"name": "read_file", "arguments": '{"path": "test.txt"}'}
}]
},
"finish_reason": "tool_calls"
}]
}
# 2. Mock second response (final answer)
# Round 2: Model provides final answer
mock_resp2 = MagicMock()
mock_resp2.status_code = 200
mock_resp2.json.return_value = {
"choices": [{
"message": {
"role": "assistant",
"content": "File content is: Hello World"
},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 100, "completion_tokens": 20}
"choices": [{"message": {"content": "File content is: Hello World"}, "finish_reason": "stop"}]
}
mock_post.side_effect = [mock_resp1, mock_resp2]
mock_dispatch.return_value = "Hello World"
result = ai_client.send(md_content="Context", user_message="Read test.txt", base_dir=".")
assert "File content is: Hello World" in result
assert mock_dispatch.called
assert mock_dispatch.call_args[0][0] == "read_file"
assert mock_dispatch.call_args[0][1] == {"path": "test.txt"}
mock_dispatch.assert_called_with("read_file", {"path": "test.txt"})
def test_deepseek_streaming() -> None:
@patch("requests.post")
def test_deepseek_streaming(mock_post: MagicMock) -> None:
"""
Verifies that DeepSeek provider correctly aggregates streaming chunks.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
with patch("requests.post") as mock_post:
# Mock a streaming response
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
# Simulate OpenAI-style server-sent events (SSE) for streaming
# Each line starts with 'data: ' and contains a JSON object
# Mocking an iterable response for stream=True
chunks = [
'data: {"choices": [{"delta": {"role": "assistant", "content": "Hello"}, "index": 0, "finish_reason": null}]}',
'data: {"choices": [{"delta": {"content": " World"}, "index": 0, "finish_reason": null}]}',
'data: {"choices": [{"delta": {}, "index": 0, "finish_reason": "stop"}]}',
'data: [DONE]'
'data: {"choices": [{"delta": {"content": "Hello "}}]}\n',
'data: {"choices": [{"delta": {"content": "World"}}]}\n',
'data: [DONE]\n'
]
mock_response.iter_lines.return_value = [c.encode('utf-8') for c in chunks]
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Stream test", base_dir=".", stream=True)
assert result == "Hello World"