Skip to content

[plugins] port Amazon Bedrock to Python #5820

Description

@cabljac

Port of the Amazon Bedrock plugin to Python, using the Go plugin
(genkit-ai/aws-bedrock-go-plugin)
as the source of truth. Same slice discipline as the Go train
(genkit-ai/aws-bedrock-go-plugin#136).

Landing strategy

Work lands as small PRs into a shared base branch, py-bedrock-plugin,
rather than straight to main. The base branch rebases onto main
periodically; when the train completes, one PR takes the assembled plugin
to main. Reviewers get small diffs during development and the full
plugin at the end.

Plugin lives at py/plugins/amazon-bedrock, package
genkit-plugin-amazon-bedrock, module genkit.plugins.amazon_bedrock.

Port structure (Go file → Python module)

Go file Responsibility Python module
bedrock.go plugin init, model/embedder definition, cache-point part plugin.py
types.go config, roles, finish reasons, reasoning part ctor config.py, typing.py
models.go capability registry, inference-profile prefix stripping model_info.py
generate.go Converse request/response conversion converters.py + models.py
stream.go ConverseStream block-indexed reassembly models.py
embed.go Titan/Cohere/Nova embedders, batching, concurrency embedders.py
image.go Titan Image / SD / Nova Canvas via InvokeModel image.py
rerank.go Cohere Rerank via InvokeModel rerank.py

Key decisions

  • Namespace bedrock, matching Go, so model refs read
    bedrock/anthropic.claude-... in every language.
  • Plain boto3 + thread bridge, behind an internal transport seam.
    aioboto3 rejected: aiobotocore pins botocore to a narrow patch range, so
    the plugin would dictate boto3 versions for every user. A thread bridge
    (asyncio.to_thread for unary calls, a pump thread for ConverseStream)
    keeps the event loop unblocked at LLM concurrency levels. Same call as
    Strands, pydantic-ai (Should we move to aioboto3? pydantic/pydantic-ai#1222), and langchain-aws.
    All boto3 calls go through one transport module so we can swap to AWS's
    async SDK when it matures.
  • Reranker as a plugin helper. Neither runtime has a usable reranker
    primitive. Python core carries ActionKind.RERANKER
    (_core/_action.py:128) and nothing else: no define_reranker, no
    ai.rerank(), and the schema types are denylisted from codegen
    (py/scripts/schema_to_typing.py:17-28). Go has no reranker action type
    at all, though it does ship the generated
    ai.RerankerRequest/RerankerResponse types. Registering an action of
    that kind works mechanically, the registry does not constrain kind, but
    callers would be left on resolve_action plus arun with hand-rolled
    types. So rerank ships as a method on the plugin, as in Go. Worth
    revisiting if ai.rerank() lands upstream, since a registered action
    would also pick up reflection listing and tracing spans.

PR train

Tests land with each slice: pytest-asyncio unit tests plus env-gated live
tests mirroring the Go *_live_test.go matrix.

Open questions

  • boto3 version floor: Converse cache points and newer stop reasons need
    recent botocore; will pin it down at slice 3.
  • Go train items 11/13/14 (region resolution, live-test matrix, docs) are
    still open upstream; we'll port their outcomes when they land rather
    than freezing current Go behavior.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions