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_anthropic_model_client.py 11 kB

add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
fix: Update SKChatCompletionAdapter message conversion (#5749) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> The PR introduces two changes. The first change is adding a name attribute to `FunctionExecutionResult`. The motivation is that semantic kernel requires it for their function result interface and it seemed like a easy modification as `FunctionExecutionResult` is always created in the context of a `FunctionCall` which will contain the name. I'm unsure if there was a motivation to keep it out but this change makes it easier to trace which tool the result refers to and also increases api compatibility with SK. The second change is an update to how messages are mapped from autogen to semantic kernel, which includes an update/fix in the processing of function results. ## Related issue number <!-- For example: "Closes #1234" --> Related to #5675 but wont fix the underlying issue of anthropic requiring tools during AssistantAgent reflection. ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. --------- Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com>
1 year ago
add anthropic native support (#5695) <!-- Thank you for your contribution! Please review https://microsoft.github.io/autogen/docs/Contribute before opening a pull request. --> Claude 3.7 just came out. Its a pretty capable model and it would be great to support it in Autogen. This will could augment the already excellent support we have for Anthropic via the SKAdapters in the following ways - Based on the ChatCompletion API similar to the ollama and openai client - Configurable/serializable (can be dumped) .. this means it can be used easily in AGS. ## What is Supported (video below shows the client being used in autogen studio) https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b - streaming - tool callign / function calling - drop in integration with assistant agent. - multimodal support ```python from dotenv import load_dotenv import os load_dotenv() from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.models.anthropic import AnthropicChatCompletionClient model_client = AnthropicChatCompletionClient( model="claude-3-7-sonnet-20250219" ) async def get_weather(city: str) -> str: """Get the weather for a given city.""" return f"The weather in {city} is 73 degrees and Sunny." agent = AssistantAgent( name="weather_agent", model_client=model_client, tools=[get_weather], system_message="You are a helpful assistant.", # model_client_stream=True, ) # Run the agent and stream the messages to the console. async def main() -> None: await Console(agent.run_stream(task="What is the weather in New York?")) await main() ``` result ``` messages = [ UserMessage(content="Write a very short story about a dragon.", source="user"), ] # Create a stream. stream = model_client.create_stream(messages=messages) # Iterate over the stream and print the responses. print("Streamed responses:") async for response in stream: # type: ignore if isinstance(response, str): # A partial response is a string. print(response, flush=True, end="") else: # The last response is a CreateResult object with the complete message. print("\n\n------------\n") print("The complete response:", flush=True) print(response.content, flush=True) print("\n\n------------\n") print("The token usage was:", flush=True) print(response.usage, flush=True) ``` <!-- Please add a reviewer to the assignee section when you create a PR. If you don't have the access to it, we will shortly find a reviewer and assign them to your PR. --> ## Why are these changes needed? <!-- Please give a short summary of the change and the problem this solves. --> ## Related issue number <!-- For example: "Closes #1234" --> Closes #5205 Closes #5708 ## Checks - [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally. - [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR. - [ ] I've made sure all auto checks have passed. cc @rohanthacker
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import asyncio
  2. import logging
  3. import os
  4. from typing import List, Sequence
  5. import pytest
  6. from autogen_core import CancellationToken, FunctionCall
  7. from autogen_core.models import (
  8. AssistantMessage,
  9. CreateResult,
  10. FunctionExecutionResult,
  11. FunctionExecutionResultMessage,
  12. SystemMessage,
  13. UserMessage,
  14. )
  15. from autogen_core.models._types import LLMMessage
  16. from autogen_core.tools import FunctionTool
  17. from autogen_ext.models.anthropic import AnthropicChatCompletionClient
  18. def _pass_function(input: str) -> str:
  19. """Simple passthrough function."""
  20. return f"Processed: {input}"
  21. def _add_numbers(a: int, b: int) -> int:
  22. """Add two numbers together."""
  23. return a + b
  24. @pytest.mark.asyncio
  25. async def test_anthropic_basic_completion(caplog: pytest.LogCaptureFixture) -> None:
  26. """Test basic message completion with Claude."""
  27. api_key = os.getenv("ANTHROPIC_API_KEY")
  28. if not api_key:
  29. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  30. client = AnthropicChatCompletionClient(
  31. model="claude-3-haiku-20240307", # Use haiku for faster/cheaper testing
  32. api_key=api_key,
  33. temperature=0.0, # Added temperature param to test
  34. stop_sequences=["STOP"], # Added stop sequence
  35. )
  36. # Test basic completion
  37. with caplog.at_level(logging.INFO):
  38. result = await client.create(
  39. messages=[
  40. SystemMessage(content="You are a helpful assistant."),
  41. UserMessage(content="What's 2+2? Answer with just the number.", source="user"),
  42. ]
  43. )
  44. assert isinstance(result.content, str)
  45. assert "4" in result.content
  46. assert result.finish_reason == "stop"
  47. assert "LLMCall" in caplog.text and result.content in caplog.text
  48. # Test JSON output - add to existing test
  49. json_result = await client.create(
  50. messages=[
  51. UserMessage(content="Return a JSON with key 'value' set to 42", source="user"),
  52. ],
  53. json_output=True,
  54. )
  55. assert isinstance(json_result.content, str)
  56. assert "42" in json_result.content
  57. # Check usage tracking
  58. usage = client.total_usage()
  59. assert usage.prompt_tokens > 0
  60. assert usage.completion_tokens > 0
  61. @pytest.mark.asyncio
  62. async def test_anthropic_streaming(caplog: pytest.LogCaptureFixture) -> None:
  63. """Test streaming capabilities with Claude."""
  64. api_key = os.getenv("ANTHROPIC_API_KEY")
  65. if not api_key:
  66. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  67. client = AnthropicChatCompletionClient(
  68. model="claude-3-haiku-20240307",
  69. api_key=api_key,
  70. )
  71. # Test streaming completion
  72. chunks: List[str | CreateResult] = []
  73. prompt = "Count from 1 to 5. Each number on its own line."
  74. with caplog.at_level(logging.INFO):
  75. async for chunk in client.create_stream(
  76. messages=[
  77. UserMessage(content=prompt, source="user"),
  78. ]
  79. ):
  80. chunks.append(chunk)
  81. # Verify we got multiple chunks
  82. assert len(chunks) > 1
  83. # Check final result
  84. final_result = chunks[-1]
  85. assert isinstance(final_result, CreateResult)
  86. assert final_result.finish_reason == "stop"
  87. assert "LLMStreamStart" in caplog.text
  88. assert "LLMStreamEnd" in caplog.text
  89. assert isinstance(final_result.content, str)
  90. for i in range(1, 6):
  91. assert str(i) in caplog.text
  92. assert prompt in caplog.text
  93. # Check content contains numbers 1-5
  94. assert isinstance(final_result.content, str)
  95. combined_content = final_result.content
  96. for i in range(1, 6):
  97. assert str(i) in combined_content
  98. @pytest.mark.asyncio
  99. async def test_anthropic_tool_calling() -> None:
  100. """Test tool calling capabilities with Claude."""
  101. api_key = os.getenv("ANTHROPIC_API_KEY")
  102. if not api_key:
  103. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  104. client = AnthropicChatCompletionClient(
  105. model="claude-3-haiku-20240307",
  106. api_key=api_key,
  107. )
  108. # Define tools
  109. pass_tool = FunctionTool(_pass_function, description="Process input text", name="process_text")
  110. add_tool = FunctionTool(_add_numbers, description="Add two numbers together", name="add_numbers")
  111. # Test tool calling with instruction to use specific tool
  112. messages: List[LLMMessage] = [
  113. SystemMessage(content="Use the tools available to help the user."),
  114. UserMessage(content="Process the text 'hello world' using the process_text tool.", source="user"),
  115. ]
  116. result = await client.create(messages=messages, tools=[pass_tool, add_tool])
  117. # Check that we got a tool call
  118. assert isinstance(result.content, list)
  119. assert len(result.content) >= 1
  120. assert isinstance(result.content[0], FunctionCall)
  121. # Check that the correct tool was called
  122. function_call = result.content[0]
  123. assert function_call.name == "process_text"
  124. # Test tool response handling
  125. messages.append(AssistantMessage(content=result.content, source="assistant"))
  126. messages.append(
  127. FunctionExecutionResultMessage(
  128. content=[
  129. FunctionExecutionResult(
  130. content="Processed: hello world",
  131. call_id=result.content[0].id,
  132. is_error=False,
  133. name=result.content[0].name,
  134. )
  135. ]
  136. )
  137. )
  138. # Get response after tool execution
  139. after_tool_result = await client.create(messages=messages)
  140. # Check we got a text response
  141. assert isinstance(after_tool_result.content, str)
  142. # Test multiple tool use
  143. multi_tool_prompt: List[LLMMessage] = [
  144. SystemMessage(content="Use the tools as needed to help the user."),
  145. UserMessage(content="First process the text 'test' and then add 2 and 3.", source="user"),
  146. ]
  147. multi_tool_result = await client.create(messages=multi_tool_prompt, tools=[pass_tool, add_tool])
  148. # We just need to verify we get at least one tool call
  149. assert isinstance(multi_tool_result.content, list)
  150. assert len(multi_tool_result.content) > 0
  151. assert isinstance(multi_tool_result.content[0], FunctionCall)
  152. @pytest.mark.asyncio
  153. async def test_anthropic_token_counting() -> None:
  154. """Test token counting functionality."""
  155. api_key = os.getenv("ANTHROPIC_API_KEY")
  156. if not api_key:
  157. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  158. client = AnthropicChatCompletionClient(
  159. model="claude-3-haiku-20240307",
  160. api_key=api_key,
  161. )
  162. messages: Sequence[LLMMessage] = [
  163. SystemMessage(content="You are a helpful assistant."),
  164. UserMessage(content="Hello, how are you?", source="user"),
  165. ]
  166. # Test token counting
  167. num_tokens = client.count_tokens(messages)
  168. assert num_tokens > 0
  169. # Test remaining token calculation
  170. remaining = client.remaining_tokens(messages)
  171. assert remaining > 0
  172. assert remaining < 200000 # Claude's max context
  173. # Test token counting with tools
  174. tools = [
  175. FunctionTool(_pass_function, description="Process input text", name="process_text"),
  176. FunctionTool(_add_numbers, description="Add two numbers together", name="add_numbers"),
  177. ]
  178. tokens_with_tools = client.count_tokens(messages, tools=tools)
  179. assert tokens_with_tools > num_tokens # Should be more tokens with tools
  180. @pytest.mark.asyncio
  181. async def test_anthropic_cancellation() -> None:
  182. """Test cancellation of requests."""
  183. api_key = os.getenv("ANTHROPIC_API_KEY")
  184. if not api_key:
  185. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  186. client = AnthropicChatCompletionClient(
  187. model="claude-3-haiku-20240307",
  188. api_key=api_key,
  189. )
  190. # Create a cancellation token
  191. cancellation_token = CancellationToken()
  192. # Schedule cancellation after a short delay
  193. async def cancel_after_delay() -> None:
  194. await asyncio.sleep(0.5) # Short delay
  195. cancellation_token.cancel()
  196. # Start task to cancel request
  197. asyncio.create_task(cancel_after_delay())
  198. # Create a request with long output
  199. with pytest.raises(asyncio.CancelledError):
  200. await client.create(
  201. messages=[
  202. UserMessage(content="Write a detailed 5-page essay on the history of computing.", source="user"),
  203. ],
  204. cancellation_token=cancellation_token,
  205. )
  206. @pytest.mark.asyncio
  207. async def test_anthropic_multimodal() -> None:
  208. """Test multimodal capabilities with Claude."""
  209. api_key = os.getenv("ANTHROPIC_API_KEY")
  210. if not api_key:
  211. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  212. # Skip if PIL is not available
  213. try:
  214. from autogen_core import Image
  215. from PIL import Image as PILImage
  216. except ImportError:
  217. pytest.skip("PIL or other dependencies not installed")
  218. client = AnthropicChatCompletionClient(
  219. model="claude-3-5-sonnet-latest", # Use a model that supports vision
  220. api_key=api_key,
  221. )
  222. # Use a simple test image that's reliable
  223. # 1. Create a simple colored square image
  224. width, height = 100, 100
  225. color = (255, 0, 0) # Red
  226. pil_image = PILImage.new("RGB", (width, height), color)
  227. # 2. Convert to autogen_core Image format
  228. img = Image(pil_image)
  229. # Test multimodal message
  230. result = await client.create(
  231. messages=[
  232. UserMessage(content=["What color is this square? Answer in one word.", img], source="user"),
  233. ]
  234. )
  235. # Verify we got a response describing the image
  236. assert isinstance(result.content, str)
  237. assert len(result.content) > 0
  238. assert "red" in result.content.lower()
  239. assert result.finish_reason == "stop"
  240. @pytest.mark.asyncio
  241. async def test_anthropic_serialization() -> None:
  242. """Test serialization and deserialization of component."""
  243. api_key = os.getenv("ANTHROPIC_API_KEY")
  244. if not api_key:
  245. pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
  246. client = AnthropicChatCompletionClient(
  247. model="claude-3-haiku-20240307",
  248. api_key=api_key,
  249. )
  250. # Serialize and deserialize
  251. model_client_config = client.dump_component()
  252. assert model_client_config is not None
  253. assert model_client_config.config is not None
  254. loaded_model_client = AnthropicChatCompletionClient.load_component(model_client_config)
  255. assert loaded_model_client is not None
  256. assert isinstance(loaded_model_client, AnthropicChatCompletionClient)