Skip to content

.NET: Python: Native support for Bedrock-hosted models (Anthropic, Cohere, etc.) in Python SDK#2560

Closed
duttastunil wants to merge 3 commits intomicrosoft:mainfrom
duttastunil:feature/bedrock-2524-changes
Closed

.NET: Python: Native support for Bedrock-hosted models (Anthropic, Cohere, etc.) in Python SDK#2560
duttastunil wants to merge 3 commits intomicrosoft:mainfrom
duttastunil:feature/bedrock-2524-changes

Conversation

@duttastunil
Copy link
Contributor

@duttastunil duttastunil commented Dec 1, 2025

Motivation and Context

The current Python SDK for the Microsoft Agent Framework requires users to route requests to Bedrock models via the generic OpenAI-compatible API interface. This approach has several drawbacks:

It does not natively recognize specific model IDs (e.g., anthropic.claude-3-5-sonnet-20240620-v1:0).
It may lack native support for provider-specific parameters or functionality (like Anthropic's specific messaging API structure, context windows, or token cost tracking).
It creates a less intuitive configuration experience compared to native integrations for Azure OpenAI or generic OpenAI services.
I would like to request dedicated, native client classes and configuration support within the Python SDK to directly integrate models hosted on Amazon Bedrock.

Description

Below are the details of the BedrockChatClient:

  1. Async implementation of the Agent Framework BaseChatClient that targets Amazon Bedrock’s Converse API.
  2. Handles provider setup: reads Bedrock credentials/region from env (via BedrockSettings), builds a boto3 bedrock-runtime client with the AF user-agent, and exposes service_url.
  3. Converts framework messages and tools into Bedrock-compatible payloads (system prompts, content blocks, tool specs/choices) while enforcing Bedrock request rules (e.g., aligning tool results with pending tool calls).
  4. Issues converse calls and adapts results back into Agent Framework structures: ChatResponse, FunctionCallContent, FunctionResultContent, usage metrics, and finish reasons.
  5. Supports streaming via _inner_get_streaming_response, automatically adds tool usage telemetry (use_function_invocation), middleware hooks, and OpenTelemetry metadata (use_observability).

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • This is not a breaking change
image

@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation python labels Dec 1, 2025
Copy link
Member

@eavanvalkenburg eavanvalkenburg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments on the code.
The folder itself should be python/packages/bedrock with agent_framework_bedrock inside, next to the pyproject and other files.
And we are missing creating a folder inside the core package called amazon that lazy loads from agent_framework_bedrock (look at the Anthropic folder for how)


[project.optional-dependencies]
dev = [
"pytest>=8.3.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already install pytest as a dev dependency

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should just be samples/amazon/<sample name>.py

@@ -0,0 +1,63 @@
from __future__ import annotations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this necessary?

ToolMode,
ai_function,
)
from agent_framework_bedrock import BedrockChatClient
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from agent_framework_bedrock import BedrockChatClient
from agent_framework.amazon import BedrockChatClient

@@ -0,0 +1,504 @@
# Copyright (c) Microsoft. All rights reserved.

from __future__ import annotations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't need this.

access_key: str | None = None,
secret_key: str | None = None,
session_token: str | None = None,
bedrock_runtime_client: BaseClient | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency use:

Suggested change
bedrock_runtime_client: BaseClient | None = None,
client: BaseClient | None = None,

**kwargs: Any,
) -> ChatResponse:
request = self._build_converse_request(messages, chat_options, **kwargs)
raw_response = await asyncio.to_thread(self._bedrock_client.converse, **request)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there no native async method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AWS’s Bedrock runtime SDK is exposed only through boto3/botocore, which are synchronous clients. There isn’t an official async interface (no converse_async or async-aware session) today.

chat_options: ChatOptions,
**kwargs: Any,
) -> AsyncIterable[ChatResponseUpdate]:
response = await self._inner_get_response(messages=messages, chat_options=chat_options, **kwargs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and no streaming method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think AWS has a ConverseStream API in preview for select providers, but it isn’t in the generally available boto3 client yet, and it doesn’t cover every model. Until the official SDK exposes a stable streaming method, we can’t add a native streaming implementation. The current shim keeps our interface consistent and can be upgraded once AWS ships wider support.

payload["system"] = system_prompts

inference_config: dict[str, Any] = {}
if chat_options.max_tokens is not None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if chat_options.max_tokens is not None:
inference_config["maxTokens"] = chat_options.max_tokens if chat_options.max_tokens is not None else DEFAULT_MAX_TOKENS

"Bedrock model_id is required. Set via chat options or BEDROCK_CHAT_MODEL_ID environment variable."
)

system_prompts = self._extract_system_prompts(messages)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in these two functions, we are looping through the messages twice, maybe combine and return the first part of the payload

@duttastunil
Copy link
Contributor Author

@eavanvalkenburg - I addressed all the comments on this PR, Please have a look on the latest code/PR. Thanks!!

@duttastunil
Copy link
Contributor Author

Updated python/packages/core/agent_framework/_workflows/_validation.py due to the below issue.

Poe => ruff check
RUF052 Local dummy variable _e is accessed
--> agent_framework_workflows_validation.py:152:17
|
150 | if self._edges: # Only evaluate when the workflow defines edges
151 | edge_executor_ids: set[str] = set()
152 | for _e in self._edges:
| ^^
153 | edge_executor_ids.add(_e.source_id)
154 | edge_executor_ids.add(_e.target_id)
|
help: Remove leading underscores

Found 1 error.
No fixes available (1 hidden fix can be enabled with the --unsafe-fixes option).
Error: Sequence aborted after failed subtask 'pre-commit-check[1]'

@duttastunil duttastunil requested a review from a team as a code owner December 3, 2025 17:31
@github-actions github-actions bot changed the title Python: Native support for Bedrock-hosted models (Anthropic, Cohere, etc.) in Python SDK .NET: Python: Native support for Bedrock-hosted models (Anthropic, Cohere, etc.) in Python SDK Dec 3, 2025
@duttastunil
Copy link
Contributor Author

duttastunil commented Dec 3, 2025

@eavanvalkenburg - Since I ran precommit check command and other commands on my local, it seems multiple file changed,
I created a new PR just to keep the PR clean for review. I addressed all the review comments in this PR, Please have a look.

https://github.com/microsoft/agent-framework/pull/2610/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation .NET python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants