feat: add QR login and browser-backed web tools
This commit is contained in:
101
tests/test_llm.py
Normal file
101
tests/test_llm.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from micro_agents import Conversation, LlmMessage, Tool, ToolCallMessage, ToolCallResponseMessage, UserMessage
|
||||
from micro_agents.conversation import ReasoningMessage
|
||||
|
||||
from app.llm import ChatCompletionsLLM
|
||||
|
||||
|
||||
class ChatCompletionsLlmTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_uses_chat_completions_with_system_prompt_and_thinking(self) -> None:
|
||||
response_message = SimpleNamespace(
|
||||
content="done",
|
||||
reasoning_content="reasoning",
|
||||
tool_calls=None,
|
||||
)
|
||||
create = AsyncMock(
|
||||
return_value=SimpleNamespace(
|
||||
choices=[SimpleNamespace(message=response_message)],
|
||||
)
|
||||
)
|
||||
llm = ChatCompletionsLLM("https://glm.example/v4", "key", "glm-model")
|
||||
llm._ai = SimpleNamespace( # type: ignore[assignment]
|
||||
chat=SimpleNamespace(completions=SimpleNamespace(create=create))
|
||||
)
|
||||
|
||||
result = await llm.ask(
|
||||
Conversation([UserMessage("hello")]),
|
||||
[],
|
||||
instructions="system prompt",
|
||||
thinking=True,
|
||||
)
|
||||
|
||||
request = create.await_args.kwargs
|
||||
self.assertEqual(request["model"], "glm-model")
|
||||
self.assertEqual(
|
||||
request["messages"],
|
||||
[
|
||||
{"role": "system", "content": "system prompt"},
|
||||
{"role": "user", "content": "hello"},
|
||||
],
|
||||
)
|
||||
self.assertEqual(request["extra_body"], {"thinking": {"type": "enabled"}})
|
||||
self.assertIsInstance(result[0], ReasoningMessage)
|
||||
self.assertIsInstance(result[1], LlmMessage)
|
||||
|
||||
async def test_serializes_and_parses_tool_calls(self) -> None:
|
||||
model_call = SimpleNamespace(
|
||||
id="call-2",
|
||||
function=SimpleNamespace(name="lookup", arguments='{"query":"news"}'),
|
||||
)
|
||||
create = AsyncMock(
|
||||
return_value=SimpleNamespace(
|
||||
choices=[
|
||||
SimpleNamespace(
|
||||
message=SimpleNamespace(
|
||||
content="",
|
||||
reasoning_content=None,
|
||||
tool_calls=[model_call],
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
llm = ChatCompletionsLLM("https://glm.example/v4", "key", "glm-model")
|
||||
llm._ai = SimpleNamespace( # type: ignore[assignment]
|
||||
chat=SimpleNamespace(completions=SimpleNamespace(create=create))
|
||||
)
|
||||
|
||||
def lookup(query: str) -> str:
|
||||
"""Look up a query."""
|
||||
return query
|
||||
|
||||
conversation = Conversation(
|
||||
[
|
||||
UserMessage("find it"),
|
||||
ReasoningMessage("need a tool"),
|
||||
LlmMessage("checking"),
|
||||
ToolCallMessage("call-1", "lookup", {"query": "weather"}),
|
||||
ToolCallResponseMessage("call-1", "sunny"),
|
||||
]
|
||||
)
|
||||
result = await llm.ask(conversation, [Tool(lookup)], thinking=False)
|
||||
|
||||
request = create.await_args.kwargs
|
||||
self.assertEqual(request["extra_body"], {"thinking": {"type": "disabled"}})
|
||||
self.assertEqual(request["tools"][0]["type"], "function")
|
||||
self.assertEqual(request["tools"][0]["function"]["name"], "lookup")
|
||||
self.assertEqual(request["messages"][1]["role"], "assistant")
|
||||
self.assertEqual(request["messages"][1]["reasoning_content"], "need a tool")
|
||||
self.assertEqual(request["messages"][2]["role"], "tool")
|
||||
self.assertIsInstance(result[0], ToolCallMessage)
|
||||
self.assertEqual(result[0].tool_name(), "lookup")
|
||||
self.assertEqual(result[0].arguments(), {"query": "news"})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user