You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_model_client.py 6.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import asyncio
  2. from typing import Any, AsyncGenerator, List
  3. import pytest
  4. from agnext.components import Image
  5. from agnext.components.models import (
  6. AssistantMessage,
  7. AzureOpenAIChatCompletionClient,
  8. CreateResult,
  9. FunctionExecutionResult,
  10. FunctionExecutionResultMessage,
  11. LLMMessage,
  12. OpenAIChatCompletionClient,
  13. SystemMessage,
  14. UserMessage,
  15. )
  16. from agnext.components.models._model_info import resolve_model
  17. from agnext.components.tools import FunctionTool
  18. from agnext.core import CancellationToken
  19. from openai.resources.chat.completions import AsyncCompletions
  20. from openai.types.chat.chat_completion import ChatCompletion, Choice
  21. from openai.types.chat.chat_completion_chunk import ChatCompletionChunk, ChoiceDelta
  22. from openai.types.chat.chat_completion_chunk import Choice as ChunkChoice
  23. from openai.types.chat.chat_completion_message import ChatCompletionMessage
  24. from openai.types.completion_usage import CompletionUsage
  25. async def _mock_create_stream(*args: Any, **kwargs: Any) -> AsyncGenerator[ChatCompletionChunk, None]:
  26. model = resolve_model(kwargs.get("model", "gpt-4o"))
  27. chunks = ["Hello", " Another Hello", " Yet Another Hello"]
  28. for chunk in chunks:
  29. await asyncio.sleep(0.1)
  30. yield ChatCompletionChunk(
  31. id="id",
  32. choices=[
  33. ChunkChoice(
  34. finish_reason="stop",
  35. index=0,
  36. delta=ChoiceDelta(
  37. content=chunk,
  38. role="assistant",
  39. ),
  40. )
  41. ],
  42. created=0,
  43. model=model,
  44. object="chat.completion.chunk",
  45. )
  46. async def _mock_create(
  47. *args: Any, **kwargs: Any
  48. ) -> ChatCompletion | AsyncGenerator[ChatCompletionChunk, None]:
  49. stream = kwargs.get("stream", False)
  50. model = resolve_model(kwargs.get("model", "gpt-4o"))
  51. if not stream:
  52. await asyncio.sleep(0.1)
  53. return ChatCompletion(
  54. id="id",
  55. choices=[
  56. Choice(finish_reason="stop", index=0, message=ChatCompletionMessage(content="Hello", role="assistant"))
  57. ],
  58. created=0,
  59. model=model,
  60. object="chat.completion",
  61. usage=CompletionUsage(prompt_tokens=0, completion_tokens=0, total_tokens=0),
  62. )
  63. else:
  64. return _mock_create_stream(*args, **kwargs)
  65. @pytest.mark.asyncio
  66. async def test_openai_chat_completion_client() -> None:
  67. client = OpenAIChatCompletionClient(model="gpt-4o", api_key="api_key")
  68. assert client
  69. @pytest.mark.asyncio
  70. async def test_azure_openai_chat_completion_client() -> None:
  71. client = AzureOpenAIChatCompletionClient(
  72. model="gpt-4o",
  73. api_key="api_key",
  74. api_version="2020-08-04",
  75. azure_endpoint="https://dummy.com",
  76. model_capabilities={"vision": True, "function_calling": True, "json_output": True},
  77. )
  78. assert client
  79. @pytest.mark.asyncio
  80. async def test_openai_chat_completion_client_create(monkeypatch: pytest.MonkeyPatch) -> None:
  81. monkeypatch.setattr(AsyncCompletions, "create", _mock_create)
  82. client = OpenAIChatCompletionClient(model="gpt-4o", api_key="api_key")
  83. result = await client.create(messages=[UserMessage(content="Hello", source="user")])
  84. assert result.content == "Hello"
  85. @pytest.mark.asyncio
  86. async def test_openai_chat_completion_client_create_stream(monkeypatch: pytest.MonkeyPatch) -> None:
  87. monkeypatch.setattr(AsyncCompletions, "create", _mock_create)
  88. client = OpenAIChatCompletionClient(model="gpt-4o", api_key="api_key")
  89. chunks: List[str | CreateResult] = []
  90. async for chunk in client.create_stream(messages=[UserMessage(content="Hello", source="user")]):
  91. chunks.append(chunk)
  92. assert chunks[0] == "Hello"
  93. assert chunks[1] == " Another Hello"
  94. assert chunks[2] == " Yet Another Hello"
  95. assert isinstance(chunks[-1], CreateResult)
  96. assert chunks[-1].content == "Hello Another Hello Yet Another Hello"
  97. @pytest.mark.asyncio
  98. async def test_openai_chat_completion_client_create_cancel(monkeypatch: pytest.MonkeyPatch) -> None:
  99. monkeypatch.setattr(AsyncCompletions, "create", _mock_create)
  100. client = OpenAIChatCompletionClient(model="gpt-4o", api_key="api_key")
  101. cancellation_token = CancellationToken()
  102. task = asyncio.create_task(
  103. client.create(messages=[UserMessage(content="Hello", source="user")], cancellation_token=cancellation_token)
  104. )
  105. cancellation_token.cancel()
  106. with pytest.raises(asyncio.CancelledError):
  107. await task
  108. @pytest.mark.asyncio
  109. async def test_openai_chat_completion_client_create_stream_cancel(monkeypatch: pytest.MonkeyPatch) -> None:
  110. monkeypatch.setattr(AsyncCompletions, "create", _mock_create)
  111. client = OpenAIChatCompletionClient(model="gpt-4o", api_key="api_key")
  112. cancellation_token = CancellationToken()
  113. stream = client.create_stream(
  114. messages=[UserMessage(content="Hello", source="user")], cancellation_token=cancellation_token
  115. )
  116. assert await anext(stream)
  117. cancellation_token.cancel()
  118. with pytest.raises(asyncio.CancelledError):
  119. async for _ in stream:
  120. pass
  121. @pytest.mark.asyncio
  122. async def test_openai_chat_completion_client_count_tokens() -> None:
  123. client = OpenAIChatCompletionClient(model="gpt-4o", api_key="api_key")
  124. messages: List[LLMMessage] = [
  125. SystemMessage(content="Hello"),
  126. UserMessage(content="Hello", source="user"),
  127. AssistantMessage(content="Hello", source="assistant"),
  128. UserMessage(
  129. content=[
  130. "str1",
  131. Image.from_base64(
  132. "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
  133. ),
  134. ],
  135. source="user",
  136. ),
  137. FunctionExecutionResultMessage(content=[FunctionExecutionResult(content="Hello", call_id="1")]),
  138. ]
  139. def tool1(test: str, test2: str) -> str:
  140. return test + test2
  141. def tool2(test1: int, test2: List[int]) -> str:
  142. return str(test1) + str(test2)
  143. tools = [FunctionTool(tool1, description="example tool 1"), FunctionTool(tool2, description="example tool 2")]
  144. num_tokens = client.count_tokens(messages, tools=tools)
  145. assert num_tokens
  146. remaining_tokens = client.remaining_tokens(messages, tools=tools)
  147. assert remaining_tokens