Files
2026-07-13 12:23:54 +08:00

49 lines
2.5 KiB
Python

import unittest
from types import SimpleNamespace
from unittest.mock import AsyncMock
from agent_runtime.llm import OpenAICompatibleLLM
class AgentLLMTests(unittest.IsolatedAsyncioTestCase):
async def test_string_response_retries_before_clear_error(self):
llm = OpenAICompatibleLLM(model="test", base_url="https://example.invalid/v1", api_key="test-key")
create = AsyncMock(side_effect=["data: [DONE]", "bad response"])
llm.client = SimpleNamespace(chat=SimpleNamespace(completions=SimpleNamespace(create=create)))
with self.assertRaisesRegex(RuntimeError, "returned a string"):
await llm.complete([], [])
self.assertEqual(create.await_count, 2)
async def test_string_response_retry_can_recover(self):
llm = OpenAICompatibleLLM(model="test", base_url="https://example.invalid/v1", api_key="test-key")
create = AsyncMock(side_effect=["data: [DONE]", {"choices": [{"message": {"content": "recovered", "tool_calls": []}}]}])
llm.client = SimpleNamespace(chat=SimpleNamespace(completions=SimpleNamespace(create=create)))
message = await llm.complete([], [])
self.assertEqual(message.text, "recovered")
self.assertEqual(create.await_count, 2)
async def test_tool_request_falls_back_to_plain_chat_after_bad_tool_responses(self):
llm = OpenAICompatibleLLM(model="test", base_url="https://example.invalid/v1", api_key="test-key")
create = AsyncMock(side_effect=[
"data: [DONE]",
"data: [DONE]",
{"choices": [{"message": {"content": "plain fallback", "tool_calls": []}}]},
])
llm.client = SimpleNamespace(chat=SimpleNamespace(completions=SimpleNamespace(create=create)))
message = await llm.complete([], [{"type": "function", "function": {"name": "x", "parameters": {}}}])
self.assertEqual(message.text, "plain fallback")
self.assertEqual(create.await_count, 3)
self.assertIsNone(create.await_args_list[-1].kwargs.get("tools"))
async def test_dict_response_is_accepted(self):
llm = OpenAICompatibleLLM(model="test", base_url="https://example.invalid/v1", api_key="test-key")
llm.client = SimpleNamespace(chat=SimpleNamespace(completions=SimpleNamespace(create=AsyncMock(return_value={
"choices": [{"message": {"content": "hello", "tool_calls": []}}]
}))))
message = await llm.complete([], [])
self.assertEqual(message.text, "hello")
if __name__ == "__main__":
unittest.main()