Fix AnthropicBedrockChatCompletionClient import error (#6489)

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

Some fixes with the AnthropicBedrockChatCompletionClient 

- Ensure `AnthropicBedrockChatCompletionClient` exported and can be
imported.
- Update the BedrockInfo keys serialization - client argument can be
string (similar to api key in this ) but exported config should be
Secret
- Replace `AnthropicBedrock` with `AsyncAnthropicBedrock` : client
should be async to work with the ag stack and the BaseAnthropicClient it
inherits from
- Improve `AnthropicBedrockChatCompletionClient` docstring to use the
correct client arguments rather than serialized dict format.

Expect

```python
from autogen_ext.models.anthropic import AnthropicBedrockChatCompletionClient, BedrockInfo
from autogen_core.models import UserMessage, ModelInfo


async def main():
    anthropic_client = AnthropicBedrockChatCompletionClient(
        model="anthropic.claude-3-5-sonnet-20240620-v1:0",
        temperature=0.1,
        model_info=ModelInfo(vision=False, function_calling=True,
                             json_output=False, family="unknown", structured_output=True),
        bedrock_info=BedrockInfo(
            aws_access_key="<aws_access_key>",
            aws_secret_key="<aws_secret_key>",
            aws_session_token="<aws_session_token>",
            aws_region="<aws_region>",
        ),
    )
    # type: ignore
    result = await anthropic_client.create([UserMessage(content="What is the capital of France?", source="user")])
    print(result)

await main()
```

<!-- 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 #6483 

## 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: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
Victor Dibia 2025-05-10 09:12:02 -07:00 committed by GitHub
parent 3db7a29403
commit 6427c07f5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 35 deletions

View File

@ -1,4 +1,8 @@
from ._anthropic_client import AnthropicChatCompletionClient, BaseAnthropicChatCompletionClient
from ._anthropic_client import (
AnthropicBedrockChatCompletionClient,
AnthropicChatCompletionClient,
BaseAnthropicChatCompletionClient,
)
from .config import (
AnthropicBedrockClientConfiguration,
AnthropicBedrockClientConfigurationConfigModel,
@ -10,6 +14,7 @@ from .config import (
__all__ = [
"AnthropicChatCompletionClient",
"AnthropicBedrockChatCompletionClient",
"BaseAnthropicChatCompletionClient",
"AnthropicClientConfiguration",
"AnthropicBedrockClientConfiguration",

View File

@ -5,8 +5,6 @@ import json
import logging
import re
import warnings
# from asyncio import Task
from typing import (
Any,
AsyncGenerator,
@ -25,7 +23,7 @@ from typing import (
)
import tiktoken
from anthropic import AnthropicBedrock, AsyncAnthropic, AsyncStream
from anthropic import AsyncAnthropic, AsyncAnthropicBedrock, AsyncStream
from anthropic.types import (
Base64ImageSourceParam,
ContentBlock,
@ -1121,7 +1119,7 @@ class AnthropicBedrockChatCompletionClient(
BaseAnthropicChatCompletionClient, Component[AnthropicBedrockClientConfigurationConfigModel]
):
"""
Chat completion client for Anthropic's Claude models.
Chat completion client for Anthropic's Claude models on AWS Bedrock.
Args:
model (str): The Claude model to use (e.g., "claude-3-sonnet-20240229", "claude-3-opus-20240229")
@ -1145,28 +1143,24 @@ class AnthropicBedrockChatCompletionClient(
.. code-block:: python
import asyncio
from autogen_ext.models.anthropic import AnthropicBedrockChatCompletionClient
from autogen_core.models import UserMessage
from autogen_ext.models.anthropic import AnthropicBedrockChatCompletionClient, BedrockInfo
from autogen_core.models import UserMessage, ModelInfo
async def main():
config = {
"model": "anthropic.claude-3-5-sonnet-20240620-v1:0",
"temperature": 0.1,
"model_info": {
"vision": True,
"function_calling": True,
"json_output": True,
"family": ModelFamily.CLAUDE_3_5_SONNET,
},
"bedrock_info": {
"aws_access_key": "<aws_access_key>",
"aws_secret_key": "<aws_secret_key>",
"aws_session_token": "<aws_session_token>",
"aws_region": "<aws_region>",
},
}
anthropic_client = AnthropicBedrockChatCompletionClient(**config)
anthropic_client = AnthropicBedrockChatCompletionClient(
model="anthropic.claude-3-5-sonnet-20240620-v1:0",
temperature=0.1,
model_info=ModelInfo(
vision=False, function_calling=True, json_output=False, family="unknown", structured_output=True
),
bedrock_info=BedrockInfo(
aws_access_key="<aws_access_key>",
aws_secret_key="<aws_secret_key>",
aws_session_token="<aws_session_token>",
aws_region="<aws_region>",
),
)
result = await anthropic_client.create([UserMessage(content="What is the capital of France?", source="user")]) # type: ignore
print(result)
@ -1178,11 +1172,11 @@ class AnthropicBedrockChatCompletionClient(
component_type = "model"
component_config_schema = AnthropicBedrockClientConfigurationConfigModel
component_provider_override = "autogen_ext.models.anthropic.AnthropicChatCompletionClient"
component_provider_override = "autogen_ext.models.anthropic.AnthropicBedrockChatCompletionClient"
def __init__(self, **kwargs: Unpack[AnthropicBedrockClientConfiguration]):
if "model" not in kwargs:
raise ValueError("model is required for AnthropicChatCompletionClient")
raise ValueError("model is required for AnthropicBedrockChatCompletionClient")
self._raw_config: Dict[str, Any] = dict(kwargs).copy()
copied_args = dict(kwargs).copy()
@ -1201,11 +1195,11 @@ class AnthropicBedrockChatCompletionClient(
# Handle bedrock_info as secretestr
aws_region = bedrock_info["aws_region"]
aws_access_key = bedrock_info["aws_access_key"].get_secret_value()
aws_secret_key = bedrock_info["aws_secret_key"].get_secret_value()
aws_session_token = bedrock_info["aws_session_token"].get_secret_value()
aws_access_key = bedrock_info["aws_access_key"]
aws_secret_key = bedrock_info["aws_secret_key"]
aws_session_token = bedrock_info["aws_session_token"]
client = AnthropicBedrock(
client = AsyncAnthropicBedrock(
aws_access_key=aws_access_key,
aws_secret_key=aws_secret_key,
aws_session_token=aws_session_token,

View File

@ -26,11 +26,11 @@ class BedrockInfo(TypedDict):
"""
aws_access_key: Required[SecretStr]
aws_access_key: Required[str]
"""Access key for the aws account to gain bedrock model access"""
aws_secret_key: Required[SecretStr]
aws_secret_key: Required[str]
"""Access secret key for the aws account to gain bedrock model access"""
aws_session_token: Required[SecretStr]
aws_session_token: Required[str]
"""aws session token for the aws account to gain bedrock model access"""
aws_region: Required[str]
"""aws region for the aws account to gain bedrock model access"""
@ -83,5 +83,15 @@ class AnthropicClientConfigurationConfigModel(BaseAnthropicClientConfigurationCo
tool_choice: Union[Literal["auto", "any", "none"], Dict[str, Any]] | None = None
class BedrockInfoConfigModel(TypedDict):
aws_access_key: Required[SecretStr]
"""Access key for the aws account to gain bedrock model access"""
aws_session_token: Required[SecretStr]
"""aws session token for the aws account to gain bedrock model access"""
aws_region: Required[str]
"""aws region for the aws account to gain bedrock model access"""
aws_secret_key: Required[SecretStr]
class AnthropicBedrockClientConfigurationConfigModel(AnthropicClientConfigurationConfigModel):
bedrock_info: BedrockInfo | None = None
bedrock_info: BedrockInfoConfigModel | None = None

View File

@ -10,12 +10,17 @@ from autogen_core.models import (
CreateResult,
FunctionExecutionResult,
FunctionExecutionResultMessage,
ModelInfo,
SystemMessage,
UserMessage,
)
from autogen_core.models._types import LLMMessage
from autogen_core.tools import FunctionTool
from autogen_ext.models.anthropic import AnthropicChatCompletionClient
from autogen_ext.models.anthropic import (
AnthropicBedrockChatCompletionClient,
AnthropicChatCompletionClient,
BedrockInfo,
)
def _pass_function(input: str) -> str:
@ -46,6 +51,29 @@ async def test_anthropic_serialization_api_key() -> None:
client2 = AnthropicChatCompletionClient.load_component(config)
assert client2
bedrock_client = AnthropicBedrockChatCompletionClient(
model="claude-3-haiku-20240307", # Use haiku for faster/cheaper testing
api_key="sk-password",
model_info=ModelInfo(
vision=False, function_calling=True, json_output=False, family="unknown", structured_output=True
),
bedrock_info=BedrockInfo(
aws_access_key="<aws_access_key>",
aws_secret_key="<aws_secret_key>",
aws_session_token="<aws_session_token>",
aws_region="<aws_region>",
),
)
assert bedrock_client
bedrock_config = bedrock_client.dump_component()
assert bedrock_config
assert "sk-password" not in str(bedrock_config)
serialized_bedrock_config = bedrock_config.model_dump_json()
assert serialized_bedrock_config
assert "sk-password" not in serialized_bedrock_config
bedrock_client2 = AnthropicBedrockChatCompletionClient.load_component(bedrock_config)
assert bedrock_client2
@pytest.mark.asyncio
async def test_anthropic_basic_completion(caplog: pytest.LogCaptureFixture) -> None: