keel-llm-adapter-bedrock
A reference
keel-llm-protocoladapter for AWS Bedrock — the enterprise gateway. Use Claude / Llama / Titan / Mistral / Cohere models hosted on Bedrock with Keel's vendor-neutral protocol + reliability + observability stack.
Try it in 5 minutes: the agentic reference demo —
docker compose upbrings up Jaeger + an agent that exercises the full failover stack. (Swap inBedrockAdapterfor the enterprise version.)
Is this for you?
Adopt when — you're on AWS and your model access is via Bedrock (Anthropic Claude, Meta Llama, Mistral, Cohere, Amazon Titan, or other Bedrock-hosted models). You want one stack across direct providers + Bedrock — same ResilientClient, same typed errors, same observability — without writing AWS-specific glue throughout your codebase.
Skip when — you call Bedrock directly with boto3 in a simple single-model app and don't need failover / observability / vendor-neutral wiring. The official AWS SDKs have a wider surface (image generation, RAG knowledge bases, agents-for-bedrock features).
Install
pip install keel-llm-adapter-bedrock # pulls in keel-llm-protocol + httpx + botocore (for SigV4)
Note on dependencies: we use
botocore.auth.SigV4Authfor request signing but send viahttpx, not boto3. This keeps the [full] OTel story working —opentelemetry-instrumentation-httpx(fromkeel-llm-otel[full]) sees each Bedrock call as a real distributed-trace span withtraceparentpropagation.
Use
import os
import asyncio
from keel_llm_adapter_bedrock import BedrockAdapter
from keel_llm_protocol import user
from keel_llm_protocol.errors import RateLimitError, AdapterError
adapter = BedrockAdapter(
model="anthropic.claude-3-5-sonnet-20241022-v2:0",
region="us-east-1",
# Credentials: explicit kwargs OR env vars (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN).
aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
)
async def main() -> None:
try:
resp = await adapter.generate([user("Explain Bedrock briefly.")])
print(resp.text, resp.usage.total_tokens, resp.finish_reason)
except RateLimitError as e:
# Bedrock throttling — healthy but rate-limited; the keel-llm-reliability
# ResilientClient defers to the rate-limiter instead of tripping the breaker.
...
except AdapterError as e:
if e.retryable:
... # transient / timeout — retry or fail over
else:
raise # auth / bad-request / context / content — fail fast
asyncio.run(main())
In a multi-provider ResilientClient (the enterprise on-ramp)
The reason most enterprise teams reach for this package — mix Bedrock with direct providers in one ResilientClient:
from keel_llm_reliability import ResilientClient, Request
from keel_llm_adapter_bedrock import BedrockAdapter
from keel_llm_adapter_openai import OpenAIAdapter
from keel_llm_protocol import user
client = ResilientClient([
BedrockAdapter(model="anthropic.claude-3-5-sonnet-20241022-v2:0", region="us-east-1"),
OpenAIAdapter(model="gpt-4o-mini", api_key=os.environ["OPENAI_API_KEY"], provider="openai"),
])
result = await client.failover(Request(messages=[user("Hi")]))
# Bedrock throttles → fails over to OpenAI. Same agent code; same Attempt trail.
Tools
BedrockAdapter implements ToolCallingModelAdapter. The Converse API's toolConfig + toolUse/toolResult blocks are mapped to / from ToolSpec + ToolCall:
from keel_llm_protocol import ToolSpec
weather = ToolSpec(
name="get_weather",
description="Get weather for a city.",
parameters={"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
)
resp = await adapter.generate_with_tools([user("Weather in SF?")], [weather])
for call in resp.tool_calls:
print(call.name, call.arguments)
How Bedrock diverges — and where it's handled
| Bedrock divergence | Absorbed by |
|---|---|
| SigV4 request signing | adapter signs every request via botocore.auth.SigV4Auth (boto3 client not required) |
messages / system / content blocks shape (Converse) |
adapter rebuilds from Messages; system lifted to top-level |
toolUse / toolResult content blocks |
mapped to / from ToolCall + tool role messages |
toolConfig.toolChoice (auto / any / tool) |
mapped from ToolChoice |
Required maxTokens |
default_max_tokens (4096) supplied when unset |
AWS error envelope (__type + message) |
mapped to the standard error taxonomy below |
stopReason (end_turn / max_tokens / tool_use / content_filtered / guardrail_intervened / …) |
mapped to FinishReason (unmapped → unknown) |
Error mapping
| Bedrock exception / status | Raised |
|---|---|
ThrottlingException / ServiceQuotaExceededException / 429 |
RateLimitError(retry_after=…) — retryable |
AccessDeniedException / UnrecognizedClientException / InvalidSignatureException / 401 / 403 |
AuthenticationError — terminal (persistent model-level; records a breaker failure) |
ValidationException with context-length keywords |
ContextLengthError — terminal |
ValidationException (other) / ResourceNotFoundException |
BadRequestError — terminal |
ServiceUnavailableException / InternalServerException / ModelTimeoutException / ModelErrorException / 5xx |
TransientError — retryable |
| HTTP timeout / connection error | AdapterTimeoutError / TransientError — retryable |
Known limitation
Streaming via converse-stream is not in v0.1.0. Bedrock streams use AWS event-stream binary framing (not SSE), which needs its own parser. Planned for 0.2; capabilities correctly excludes "streaming" so consumers can route around it via capabilities introspection without surprise.
Status
0.1.0 — 0.x while the API stabilizes through year one (breaking changes possible at minor bumps, documented in the CHANGELOG; pin exact versions).
The Keel toolkit
Composable, vendor-neutral LLM reliability libraries on PyPI:
keel-llm-reliability · keel-llm-protocol · keel-llm-adapter-openai · keel-llm-adapter-anthropic · keel-llm-adapter-google · keel-llm-adapter-bedrock · keel-circuit-breaker · keel-llm-otel
MIT licensed.
Metadata
Release files for keel-llm-adapter-bedrock 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| keel_llm_adapter_bedrock-0.1.0.tar.gz | 11.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keel_llm_adapter_bedrock-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.8 kB
Release files / keel_llm_adapter_bedrock-0.1.0.tar.gz
| Download URL | keel_llm_adapter_bedrock-0.1.0.tar.gz |
|---|---|
| Size | 11.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ec89e3ddba03795e8db50660f51a447f511cea8b125806d32cc7a860814014a0
|
|
BLAKE2b-256 checksum How to use checksums |
cb26c4697d57353ce2f47bdb90e7f7c7a093c65e9c9ecc3ed32ce36a3d45edea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 24, 2026.
Transparency logRelease files / keel_llm_adapter_bedrock-0.1.0-py3-none-any.whl
| Download URL | keel_llm_adapter_bedrock-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d5b20dcbca29e540df9ea55a846247bbf944ca7c2b6832fa50a5a746c78a9262
|
|
BLAKE2b-256 checksum How to use checksums |
1daf7d524a621ea36b3dfe17e43e7f6f76cc15e71fee36834977b9c22e6e93bd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 24, 2026.
Transparency logSecurity for keel-llm-adapter-bedrock 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for keel_llm_adapter_bedrock-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.