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
2025-02-25 23:27:41 -08:00
|
|
|
import asyncio
|
2025-03-07 16:04:45 -08:00
|
|
|
import logging
|
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
2025-02-25 23:27:41 -08:00
|
|
|
import os
|
|
|
|
from typing import List, Sequence
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
from autogen_core import CancellationToken, FunctionCall
|
|
|
|
from autogen_core.models import (
|
|
|
|
AssistantMessage,
|
|
|
|
CreateResult,
|
|
|
|
FunctionExecutionResult,
|
|
|
|
FunctionExecutionResultMessage,
|
|
|
|
SystemMessage,
|
|
|
|
UserMessage,
|
|
|
|
)
|
|
|
|
from autogen_core.models._types import LLMMessage
|
|
|
|
from autogen_core.tools import FunctionTool
|
|
|
|
from autogen_ext.models.anthropic import AnthropicChatCompletionClient
|
|
|
|
|
|
|
|
|
|
|
|
def _pass_function(input: str) -> str:
|
|
|
|
"""Simple passthrough function."""
|
|
|
|
return f"Processed: {input}"
|
|
|
|
|
|
|
|
|
|
|
|
def _add_numbers(a: int, b: int) -> int:
|
|
|
|
"""Add two numbers together."""
|
|
|
|
return a + b
|
|
|
|
|
|
|
|
|
2025-03-13 21:29:19 -07:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_anthropic_serialization_api_key() -> None:
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307", # Use haiku for faster/cheaper testing
|
|
|
|
api_key="sk-password",
|
|
|
|
temperature=0.0, # Added temperature param to test
|
|
|
|
stop_sequences=["STOP"], # Added stop sequence
|
|
|
|
)
|
|
|
|
assert client
|
|
|
|
config = client.dump_component()
|
|
|
|
assert config
|
|
|
|
assert "sk-password" not in str(config)
|
|
|
|
serialized_config = config.model_dump_json()
|
|
|
|
assert serialized_config
|
|
|
|
assert "sk-password" not in serialized_config
|
|
|
|
client2 = AnthropicChatCompletionClient.load_component(config)
|
|
|
|
assert client2
|
|
|
|
|
|
|
|
|
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
2025-02-25 23:27:41 -08:00
|
|
|
@pytest.mark.asyncio
|
2025-03-07 16:04:45 -08:00
|
|
|
async def test_anthropic_basic_completion(caplog: pytest.LogCaptureFixture) -> None:
|
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
2025-02-25 23:27:41 -08:00
|
|
|
"""Test basic message completion with Claude."""
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307", # Use haiku for faster/cheaper testing
|
|
|
|
api_key=api_key,
|
|
|
|
temperature=0.0, # Added temperature param to test
|
|
|
|
stop_sequences=["STOP"], # Added stop sequence
|
|
|
|
)
|
|
|
|
|
|
|
|
# Test basic completion
|
2025-03-07 16:04:45 -08:00
|
|
|
with caplog.at_level(logging.INFO):
|
|
|
|
result = await client.create(
|
|
|
|
messages=[
|
|
|
|
SystemMessage(content="You are a helpful assistant."),
|
|
|
|
UserMessage(content="What's 2+2? Answer with just the number.", source="user"),
|
|
|
|
]
|
|
|
|
)
|
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
2025-02-25 23:27:41 -08:00
|
|
|
|
2025-03-07 16:04:45 -08:00
|
|
|
assert isinstance(result.content, str)
|
|
|
|
assert "4" in result.content
|
|
|
|
assert result.finish_reason == "stop"
|
|
|
|
assert "LLMCall" in caplog.text and result.content in caplog.text
|
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
2025-02-25 23:27:41 -08:00
|
|
|
|
|
|
|
# Test JSON output - add to existing test
|
|
|
|
json_result = await client.create(
|
|
|
|
messages=[
|
|
|
|
UserMessage(content="Return a JSON with key 'value' set to 42", source="user"),
|
|
|
|
],
|
|
|
|
json_output=True,
|
|
|
|
)
|
|
|
|
assert isinstance(json_result.content, str)
|
|
|
|
assert "42" in json_result.content
|
|
|
|
|
|
|
|
# Check usage tracking
|
|
|
|
usage = client.total_usage()
|
|
|
|
assert usage.prompt_tokens > 0
|
|
|
|
assert usage.completion_tokens > 0
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
2025-03-11 18:02:46 -04:00
|
|
|
async def test_anthropic_streaming(caplog: pytest.LogCaptureFixture) -> None:
|
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
2025-02-25 23:27:41 -08:00
|
|
|
"""Test streaming capabilities with Claude."""
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307",
|
|
|
|
api_key=api_key,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Test streaming completion
|
|
|
|
chunks: List[str | CreateResult] = []
|
2025-03-11 18:02:46 -04:00
|
|
|
prompt = "Count from 1 to 5. Each number on its own line."
|
|
|
|
with caplog.at_level(logging.INFO):
|
|
|
|
async for chunk in client.create_stream(
|
|
|
|
messages=[
|
|
|
|
UserMessage(content=prompt, source="user"),
|
|
|
|
]
|
|
|
|
):
|
|
|
|
chunks.append(chunk)
|
|
|
|
# Verify we got multiple chunks
|
|
|
|
assert len(chunks) > 1
|
|
|
|
|
|
|
|
# Check final result
|
|
|
|
final_result = chunks[-1]
|
|
|
|
assert isinstance(final_result, CreateResult)
|
|
|
|
assert final_result.finish_reason == "stop"
|
|
|
|
|
|
|
|
assert "LLMStreamStart" in caplog.text
|
|
|
|
assert "LLMStreamEnd" in caplog.text
|
|
|
|
assert isinstance(final_result.content, str)
|
|
|
|
for i in range(1, 6):
|
|
|
|
assert str(i) in caplog.text
|
|
|
|
assert prompt in caplog.text
|
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
2025-02-25 23:27:41 -08:00
|
|
|
|
|
|
|
# Check content contains numbers 1-5
|
|
|
|
assert isinstance(final_result.content, str)
|
|
|
|
combined_content = final_result.content
|
|
|
|
for i in range(1, 6):
|
|
|
|
assert str(i) in combined_content
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_anthropic_tool_calling() -> None:
|
|
|
|
"""Test tool calling capabilities with Claude."""
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307",
|
|
|
|
api_key=api_key,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Define tools
|
|
|
|
pass_tool = FunctionTool(_pass_function, description="Process input text", name="process_text")
|
|
|
|
add_tool = FunctionTool(_add_numbers, description="Add two numbers together", name="add_numbers")
|
|
|
|
|
|
|
|
# Test tool calling with instruction to use specific tool
|
|
|
|
messages: List[LLMMessage] = [
|
|
|
|
SystemMessage(content="Use the tools available to help the user."),
|
|
|
|
UserMessage(content="Process the text 'hello world' using the process_text tool.", source="user"),
|
|
|
|
]
|
|
|
|
|
|
|
|
result = await client.create(messages=messages, tools=[pass_tool, add_tool])
|
|
|
|
|
|
|
|
# Check that we got a tool call
|
|
|
|
assert isinstance(result.content, list)
|
|
|
|
assert len(result.content) >= 1
|
|
|
|
assert isinstance(result.content[0], FunctionCall)
|
|
|
|
|
|
|
|
# Check that the correct tool was called
|
|
|
|
function_call = result.content[0]
|
|
|
|
assert function_call.name == "process_text"
|
|
|
|
|
|
|
|
# Test tool response handling
|
|
|
|
messages.append(AssistantMessage(content=result.content, source="assistant"))
|
|
|
|
messages.append(
|
|
|
|
FunctionExecutionResultMessage(
|
|
|
|
content=[
|
2025-03-04 09:05:54 +10:00
|
|
|
FunctionExecutionResult(
|
|
|
|
content="Processed: hello world",
|
|
|
|
call_id=result.content[0].id,
|
|
|
|
is_error=False,
|
|
|
|
name=result.content[0].name,
|
|
|
|
)
|
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
2025-02-25 23:27:41 -08:00
|
|
|
]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Get response after tool execution
|
|
|
|
after_tool_result = await client.create(messages=messages)
|
|
|
|
|
|
|
|
# Check we got a text response
|
|
|
|
assert isinstance(after_tool_result.content, str)
|
|
|
|
|
|
|
|
# Test multiple tool use
|
|
|
|
multi_tool_prompt: List[LLMMessage] = [
|
|
|
|
SystemMessage(content="Use the tools as needed to help the user."),
|
|
|
|
UserMessage(content="First process the text 'test' and then add 2 and 3.", source="user"),
|
|
|
|
]
|
|
|
|
|
|
|
|
multi_tool_result = await client.create(messages=multi_tool_prompt, tools=[pass_tool, add_tool])
|
|
|
|
|
|
|
|
# We just need to verify we get at least one tool call
|
|
|
|
assert isinstance(multi_tool_result.content, list)
|
|
|
|
assert len(multi_tool_result.content) > 0
|
|
|
|
assert isinstance(multi_tool_result.content[0], FunctionCall)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_anthropic_token_counting() -> None:
|
|
|
|
"""Test token counting functionality."""
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307",
|
|
|
|
api_key=api_key,
|
|
|
|
)
|
|
|
|
|
|
|
|
messages: Sequence[LLMMessage] = [
|
|
|
|
SystemMessage(content="You are a helpful assistant."),
|
|
|
|
UserMessage(content="Hello, how are you?", source="user"),
|
|
|
|
]
|
|
|
|
|
|
|
|
# Test token counting
|
|
|
|
num_tokens = client.count_tokens(messages)
|
|
|
|
assert num_tokens > 0
|
|
|
|
|
|
|
|
# Test remaining token calculation
|
|
|
|
remaining = client.remaining_tokens(messages)
|
|
|
|
assert remaining > 0
|
|
|
|
assert remaining < 200000 # Claude's max context
|
|
|
|
|
|
|
|
# Test token counting with tools
|
|
|
|
tools = [
|
|
|
|
FunctionTool(_pass_function, description="Process input text", name="process_text"),
|
|
|
|
FunctionTool(_add_numbers, description="Add two numbers together", name="add_numbers"),
|
|
|
|
]
|
|
|
|
tokens_with_tools = client.count_tokens(messages, tools=tools)
|
|
|
|
assert tokens_with_tools > num_tokens # Should be more tokens with tools
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_anthropic_cancellation() -> None:
|
|
|
|
"""Test cancellation of requests."""
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307",
|
|
|
|
api_key=api_key,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Create a cancellation token
|
|
|
|
cancellation_token = CancellationToken()
|
|
|
|
|
|
|
|
# Schedule cancellation after a short delay
|
|
|
|
async def cancel_after_delay() -> None:
|
|
|
|
await asyncio.sleep(0.5) # Short delay
|
|
|
|
cancellation_token.cancel()
|
|
|
|
|
|
|
|
# Start task to cancel request
|
|
|
|
asyncio.create_task(cancel_after_delay())
|
|
|
|
|
|
|
|
# Create a request with long output
|
|
|
|
with pytest.raises(asyncio.CancelledError):
|
|
|
|
await client.create(
|
|
|
|
messages=[
|
|
|
|
UserMessage(content="Write a detailed 5-page essay on the history of computing.", source="user"),
|
|
|
|
],
|
|
|
|
cancellation_token=cancellation_token,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_anthropic_multimodal() -> None:
|
|
|
|
"""Test multimodal capabilities with Claude."""
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
# Skip if PIL is not available
|
|
|
|
try:
|
|
|
|
from autogen_core import Image
|
|
|
|
from PIL import Image as PILImage
|
|
|
|
except ImportError:
|
|
|
|
pytest.skip("PIL or other dependencies not installed")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-5-sonnet-latest", # Use a model that supports vision
|
|
|
|
api_key=api_key,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Use a simple test image that's reliable
|
|
|
|
# 1. Create a simple colored square image
|
|
|
|
width, height = 100, 100
|
|
|
|
color = (255, 0, 0) # Red
|
|
|
|
pil_image = PILImage.new("RGB", (width, height), color)
|
|
|
|
|
|
|
|
# 2. Convert to autogen_core Image format
|
|
|
|
img = Image(pil_image)
|
|
|
|
|
|
|
|
# Test multimodal message
|
|
|
|
result = await client.create(
|
|
|
|
messages=[
|
|
|
|
UserMessage(content=["What color is this square? Answer in one word.", img], source="user"),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
# Verify we got a response describing the image
|
|
|
|
assert isinstance(result.content, str)
|
|
|
|
assert len(result.content) > 0
|
|
|
|
assert "red" in result.content.lower()
|
|
|
|
assert result.finish_reason == "stop"
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_anthropic_serialization() -> None:
|
|
|
|
"""Test serialization and deserialization of component."""
|
|
|
|
|
|
|
|
api_key = os.getenv("ANTHROPIC_API_KEY")
|
|
|
|
if not api_key:
|
|
|
|
pytest.skip("ANTHROPIC_API_KEY not found in environment variables")
|
|
|
|
|
|
|
|
client = AnthropicChatCompletionClient(
|
|
|
|
model="claude-3-haiku-20240307",
|
|
|
|
api_key=api_key,
|
|
|
|
)
|
|
|
|
|
|
|
|
# Serialize and deserialize
|
|
|
|
model_client_config = client.dump_component()
|
|
|
|
assert model_client_config is not None
|
|
|
|
assert model_client_config.config is not None
|
|
|
|
|
|
|
|
loaded_model_client = AnthropicChatCompletionClient.load_component(model_client_config)
|
|
|
|
assert loaded_model_client is not None
|
|
|
|
assert isinstance(loaded_model_client, AnthropicChatCompletionClient)
|