feat: add bedrock_mantle as a first-class provider with native-Anthropic and OpenAI-compatible routing - #4736
Conversation
|
|
Confidence Score: 4/5Safe to merge for Bearer-auth users; SigV4 list-models needs the empty-Accept guard before shipping to production SigV4 users. The new provider is well-structured and the Anthropic/OpenAI dispatch, streaming client separation, and ExtraHeaders cloning are all correct. The one concrete defect is in listModelsByKey: passing accept = "" to SignMantleV4Headers causes an empty Accept header to enter the SigV4 canonical request and be returned in the signed headers map, while the existing bedrock provider's GET signing omits Accept entirely. If fasthttp doesn't emit a zero-length Accept on the wire, the signature check fails for every SigV4 list-models call on the new provider. The fix is a one-line guard in SignMantleV4Headers. The companion inline comment also misstates that signAWSRequest defaults Accept to application/json (it only defaults Content-Type), which could mislead future maintainers. core/providers/bedrock/mantle.go (SignMantleV4Headers Accept handling and comment) and core/providers/bedrockmantle/bedrockmantle.go (listModelsByKey accept argument). Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Request: BedrockMantle provider] --> B{IsAnthropicModelFamily?}
B -- Yes --> C[mantleAnthropicURL\n/anthropic/v1/messages]
B -- No --> D[mantleOpenAIURL\n/v1 or /openai/v1]
C --> E{Streaming?}
D --> F{Streaming?}
E -- Yes --> G[HandleAnthropicChatCompletionStreaming\nmantleStreamingClient]
E -- No --> H[HandleAnthropicChatCompletionRequest\nmantleClient]
F -- Yes --> I[HandleOpenAIChatCompletionStreaming\nmantleStreamingClient]
F -- No --> J[HandleOpenAIChatCompletionRequest\nmantleClient]
G & H & I & J --> K{key.Value empty?}
K -- No --> L[Bearer: Authorization header]
K -- Yes --> M[SigV4: SignMantleV4Headers\nBedrockMantleKeyConfig → synthetic BedrockKeyConfig]
M --> N[signAWSRequest\nbedrock-mantle service]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Request: BedrockMantle provider] --> B{IsAnthropicModelFamily?}
B -- Yes --> C[mantleAnthropicURL\n/anthropic/v1/messages]
B -- No --> D[mantleOpenAIURL\n/v1 or /openai/v1]
C --> E{Streaming?}
D --> F{Streaming?}
E -- Yes --> G[HandleAnthropicChatCompletionStreaming\nmantleStreamingClient]
E -- No --> H[HandleAnthropicChatCompletionRequest\nmantleClient]
F -- Yes --> I[HandleOpenAIChatCompletionStreaming\nmantleStreamingClient]
F -- No --> J[HandleOpenAIChatCompletionRequest\nmantleClient]
G & H & I & J --> K{key.Value empty?}
K -- No --> L[Bearer: Authorization header]
K -- Yes --> M[SigV4: SignMantleV4Headers\nBedrockMantleKeyConfig → synthetic BedrockKeyConfig]
M --> N[signAWSRequest\nbedrock-mantle service]
Reviews (8): Last reviewed commit: "feat: adds bedrock-mantle provider" | Re-trigger Greptile |
6f73e03 to
36367b7
Compare
6358bdc to
24d4d45
Compare
|
Warning Review limit reached
More reviews will be available in 11 minutes and 46 seconds. Learn how PR review limits work. To continue reviewing without waiting, enable usage-based billing in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (14)
📝 WalkthroughWalkthroughAdds a ChangesBedrock Mantle provider support
Estimated review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
24d4d45 to
d914e21
Compare
36367b7 to
45b7753
Compare
45b7753 to
ee786b0
Compare
d914e21 to
4eb1c31
Compare
ee786b0 to
85f57cb
Compare
4eb1c31 to
dc61459
Compare
Merge activity
|
85f57cb to
d3fb617
Compare
dc61459 to
6b56b4d
Compare
The base branch was changed.
6b56b4d to
8a86083
Compare
…ropic and OpenAI-compatible routing (#4736) ## Summary Introduces `bedrock_mantle` as a first-class, standalone provider that owns the Bedrock Mantle surface (`bedrock-mantle.{region}.api.aws`). Previously, Mantle routing was handled as an internal routing decision inside the existing `bedrock` provider. The new provider gives operators a dedicated configuration surface for Claude (native Anthropic Messages API), OpenAI-compatible models (gpt-*), and Gemma models served through Mantle, without requiring a full Bedrock setup. ## Changes - Added `schemas.BedrockMantle` (`"bedrock_mantle"`) as a new `ModelProvider` constant and registered it in `StandardProviders`, `dynamicallyConfigurableProviders`, `CanProviderKeyValueBeEmpty`, and `isKeySkippingAllowed`. - Added `BedrockMantleKeyConfig` to the `Key` struct, carrying AWS credentials and region for SigV4 auth against the `bedrock-mantle` service. The existing `BedrockKeyConfig` is unchanged. - Introduced the `core/providers/bedrockmantle` package implementing the full `Provider` interface. Chat, streaming chat, Responses, and streaming Responses dispatch by model family: Anthropic-family models use the native Anthropic Messages surface (`/anthropic/v1/messages`); all others use the OpenAI-compatible surface (`/v1` or `/openai/v1`). All other operations return unsupported-operation errors. - Refactored `signAWSRequest` in the `bedrock` package to accept a `*BedrockKeyConfig` instead of individual credential fields, eliminating the now-redundant `signAWSRequestFromKey` wrapper. All call sites updated accordingly. - Exported `SignMantleV4Headers` (previously `mantleSigV4Headers`, a method on `BedrockProvider`) so the new `bedrockmantle` package can sign requests without depending on the internal Bedrock provider struct. The function now supports both `BedrockKeyConfig` and `BedrockMantleKeyConfig` by mapping the latter into a synthetic `BedrockKeyConfig` for signing, and correctly handles GET requests (nil body) for the list-models path. - Extended the Anthropic chat and Responses request builders to convert native structured outputs to tool calls for `BedrockMantle`, matching the existing `Vertex` workaround. - Added `BedrockMantle` to the comprehensive LLM test harness (`ComprehensiveTestAccount`) with key config, provider config, and a full test file covering the supported scenarios (chat, streaming, tool calls, vision, structured outputs, prompt caching, reasoning, list models) and explicitly disabling unsupported ones. - Marked `isMantleModel` in `bedrock/mantle.go` as deprecated in favour of the new provider. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Set AWS credentials and run the new provider test: ```sh export AWS_ACCESS_KEY_ID=... export AWS_SECRET_ACCESS_KEY=... export AWS_SESSION_TOKEN=... # optional, for temporary credentials export AWS_REGION=us-east-1 go test ./core/providers/bedrockmantle/... -v -run TestBedrockMantle ``` To run the full suite (skips Bedrock Mantle automatically when credentials are absent): ```sh go test ./... ``` Configure a `bedrock_mantle` provider by supplying a `BedrockMantleKeyConfig` (or a Bearer API key in `Value`) with the desired region. The region can also be embedded as a prefix in the model ID (e.g. `us-west-2/anthropic.claude-haiku-4-5`) or set at the alias level via `AliasConfig.Region`. ## Breaking changes - [ ] Yes - [x] No The `signAWSRequest` signature change is internal to the `bedrock` package and does not affect any public API. The `isMantleModel` function is deprecated but not removed. ## Security considerations AWS credentials for `BedrockMantleKeyConfig` follow the same `SecretVar` resolution pattern used by `BedrockKeyConfig` (env-var references, never inlined literals). SigV4 signing is performed per-request on the exact body bytes that are sent, so the signature always covers what is transmitted. When a Bearer API key is present it takes precedence and no AWS credentials are required. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…ropic and OpenAI-compatible routing (maximhq#4736) ## Summary Introduces `bedrock_mantle` as a first-class, standalone provider that owns the Bedrock Mantle surface (`bedrock-mantle.{region}.api.aws`). Previously, Mantle routing was handled as an internal routing decision inside the existing `bedrock` provider. The new provider gives operators a dedicated configuration surface for Claude (native Anthropic Messages API), OpenAI-compatible models (gpt-*), and Gemma models served through Mantle, without requiring a full Bedrock setup. ## Changes - Added `schemas.BedrockMantle` (`"bedrock_mantle"`) as a new `ModelProvider` constant and registered it in `StandardProviders`, `dynamicallyConfigurableProviders`, `CanProviderKeyValueBeEmpty`, and `isKeySkippingAllowed`. - Added `BedrockMantleKeyConfig` to the `Key` struct, carrying AWS credentials and region for SigV4 auth against the `bedrock-mantle` service. The existing `BedrockKeyConfig` is unchanged. - Introduced the `core/providers/bedrockmantle` package implementing the full `Provider` interface. Chat, streaming chat, Responses, and streaming Responses dispatch by model family: Anthropic-family models use the native Anthropic Messages surface (`/anthropic/v1/messages`); all others use the OpenAI-compatible surface (`/v1` or `/openai/v1`). All other operations return unsupported-operation errors. - Refactored `signAWSRequest` in the `bedrock` package to accept a `*BedrockKeyConfig` instead of individual credential fields, eliminating the now-redundant `signAWSRequestFromKey` wrapper. All call sites updated accordingly. - Exported `SignMantleV4Headers` (previously `mantleSigV4Headers`, a method on `BedrockProvider`) so the new `bedrockmantle` package can sign requests without depending on the internal Bedrock provider struct. The function now supports both `BedrockKeyConfig` and `BedrockMantleKeyConfig` by mapping the latter into a synthetic `BedrockKeyConfig` for signing, and correctly handles GET requests (nil body) for the list-models path. - Extended the Anthropic chat and Responses request builders to convert native structured outputs to tool calls for `BedrockMantle`, matching the existing `Vertex` workaround. - Added `BedrockMantle` to the comprehensive LLM test harness (`ComprehensiveTestAccount`) with key config, provider config, and a full test file covering the supported scenarios (chat, streaming, tool calls, vision, structured outputs, prompt caching, reasoning, list models) and explicitly disabling unsupported ones. - Marked `isMantleModel` in `bedrock/mantle.go` as deprecated in favour of the new provider. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Set AWS credentials and run the new provider test: ```sh export AWS_ACCESS_KEY_ID=... export AWS_SECRET_ACCESS_KEY=... export AWS_SESSION_TOKEN=... # optional, for temporary credentials export AWS_REGION=us-east-1 go test ./core/providers/bedrockmantle/... -v -run TestBedrockMantle ``` To run the full suite (skips Bedrock Mantle automatically when credentials are absent): ```sh go test ./... ``` Configure a `bedrock_mantle` provider by supplying a `BedrockMantleKeyConfig` (or a Bearer API key in `Value`) with the desired region. The region can also be embedded as a prefix in the model ID (e.g. `us-west-2/anthropic.claude-haiku-4-5`) or set at the alias level via `AliasConfig.Region`. ## Breaking changes - [ ] Yes - [x] No The `signAWSRequest` signature change is internal to the `bedrock` package and does not affect any public API. The `isMantleModel` function is deprecated but not removed. ## Security considerations AWS credentials for `BedrockMantleKeyConfig` follow the same `SecretVar` resolution pattern used by `BedrockKeyConfig` (env-var references, never inlined literals). SigV4 signing is performed per-request on the exact body bytes that are sent, so the signature always covers what is transmitted. When a Bearer API key is present it takes precedence and no AWS credentials are required. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable
…ropic and OpenAI-compatible routing (#4736) ## Summary Introduces `bedrock_mantle` as a first-class, standalone provider that owns the Bedrock Mantle surface (`bedrock-mantle.{region}.api.aws`). Previously, Mantle routing was handled as an internal routing decision inside the existing `bedrock` provider. The new provider gives operators a dedicated configuration surface for Claude (native Anthropic Messages API), OpenAI-compatible models (gpt-*), and Gemma models served through Mantle, without requiring a full Bedrock setup. ## Changes - Added `schemas.BedrockMantle` (`"bedrock_mantle"`) as a new `ModelProvider` constant and registered it in `StandardProviders`, `dynamicallyConfigurableProviders`, `CanProviderKeyValueBeEmpty`, and `isKeySkippingAllowed`. - Added `BedrockMantleKeyConfig` to the `Key` struct, carrying AWS credentials and region for SigV4 auth against the `bedrock-mantle` service. The existing `BedrockKeyConfig` is unchanged. - Introduced the `core/providers/bedrockmantle` package implementing the full `Provider` interface. Chat, streaming chat, Responses, and streaming Responses dispatch by model family: Anthropic-family models use the native Anthropic Messages surface (`/anthropic/v1/messages`); all others use the OpenAI-compatible surface (`/v1` or `/openai/v1`). All other operations return unsupported-operation errors. - Refactored `signAWSRequest` in the `bedrock` package to accept a `*BedrockKeyConfig` instead of individual credential fields, eliminating the now-redundant `signAWSRequestFromKey` wrapper. All call sites updated accordingly. - Exported `SignMantleV4Headers` (previously `mantleSigV4Headers`, a method on `BedrockProvider`) so the new `bedrockmantle` package can sign requests without depending on the internal Bedrock provider struct. The function now supports both `BedrockKeyConfig` and `BedrockMantleKeyConfig` by mapping the latter into a synthetic `BedrockKeyConfig` for signing, and correctly handles GET requests (nil body) for the list-models path. - Extended the Anthropic chat and Responses request builders to convert native structured outputs to tool calls for `BedrockMantle`, matching the existing `Vertex` workaround. - Added `BedrockMantle` to the comprehensive LLM test harness (`ComprehensiveTestAccount`) with key config, provider config, and a full test file covering the supported scenarios (chat, streaming, tool calls, vision, structured outputs, prompt caching, reasoning, list models) and explicitly disabling unsupported ones. - Marked `isMantleModel` in `bedrock/mantle.go` as deprecated in favour of the new provider. ## Type of change - [ ] Bug fix - [x] Feature - [ ] Refactor - [ ] Documentation - [ ] Chore/CI ## Affected areas - [x] Core (Go) - [ ] Transports (HTTP) - [x] Providers/Integrations - [ ] Plugins - [ ] UI (React) - [ ] Docs ## How to test Set AWS credentials and run the new provider test: ```sh export AWS_ACCESS_KEY_ID=... export AWS_SECRET_ACCESS_KEY=... export AWS_SESSION_TOKEN=... # optional, for temporary credentials export AWS_REGION=us-east-1 go test ./core/providers/bedrockmantle/... -v -run TestBedrockMantle ``` To run the full suite (skips Bedrock Mantle automatically when credentials are absent): ```sh go test ./... ``` Configure a `bedrock_mantle` provider by supplying a `BedrockMantleKeyConfig` (or a Bearer API key in `Value`) with the desired region. The region can also be embedded as a prefix in the model ID (e.g. `us-west-2/anthropic.claude-haiku-4-5`) or set at the alias level via `AliasConfig.Region`. ## Breaking changes - [ ] Yes - [x] No The `signAWSRequest` signature change is internal to the `bedrock` package and does not affect any public API. The `isMantleModel` function is deprecated but not removed. ## Security considerations AWS credentials for `BedrockMantleKeyConfig` follow the same `SecretVar` resolution pattern used by `BedrockKeyConfig` (env-var references, never inlined literals). SigV4 signing is performed per-request on the exact body bytes that are sent, so the signature always covers what is transmitted. When a Bearer API key is present it takes precedence and no AWS credentials are required. ## Checklist - [ ] I read `docs/contributing/README.md` and followed the guidelines - [x] I added/updated tests where appropriate - [ ] I updated documentation where needed - [x] I verified builds succeed (Go and UI) - [ ] I verified the CI pipeline passes locally if applicable

Summary
Introduces
bedrock_mantleas a first-class, standalone provider that owns the Bedrock Mantle surface (bedrock-mantle.{region}.api.aws). Previously, Mantle routing was handled as an internal routing decision inside the existingbedrockprovider. The new provider gives operators a dedicated configuration surface for Claude (native Anthropic Messages API), OpenAI-compatible models (gpt-*), and Gemma models served through Mantle, without requiring a full Bedrock setup.Changes
schemas.BedrockMantle("bedrock_mantle") as a newModelProviderconstant and registered it inStandardProviders,dynamicallyConfigurableProviders,CanProviderKeyValueBeEmpty, andisKeySkippingAllowed.BedrockMantleKeyConfigto theKeystruct, carrying AWS credentials and region for SigV4 auth against thebedrock-mantleservice. The existingBedrockKeyConfigis unchanged.core/providers/bedrockmantlepackage implementing the fullProviderinterface. Chat, streaming chat, Responses, and streaming Responses dispatch by model family: Anthropic-family models use the native Anthropic Messages surface (/anthropic/v1/messages); all others use the OpenAI-compatible surface (/v1or/openai/v1). All other operations return unsupported-operation errors.signAWSRequestin thebedrockpackage to accept a*BedrockKeyConfiginstead of individual credential fields, eliminating the now-redundantsignAWSRequestFromKeywrapper. All call sites updated accordingly.SignMantleV4Headers(previouslymantleSigV4Headers, a method onBedrockProvider) so the newbedrockmantlepackage can sign requests without depending on the internal Bedrock provider struct. The function now supports bothBedrockKeyConfigandBedrockMantleKeyConfigby mapping the latter into a syntheticBedrockKeyConfigfor signing, and correctly handles GET requests (nil body) for the list-models path.BedrockMantle, matching the existingVertexworkaround.BedrockMantleto the comprehensive LLM test harness (ComprehensiveTestAccount) with key config, provider config, and a full test file covering the supported scenarios (chat, streaming, tool calls, vision, structured outputs, prompt caching, reasoning, list models) and explicitly disabling unsupported ones.isMantleModelinbedrock/mantle.goas deprecated in favour of the new provider.Type of change
Affected areas
How to test
Set AWS credentials and run the new provider test:
To run the full suite (skips Bedrock Mantle automatically when credentials are absent):
go test ./...Configure a
bedrock_mantleprovider by supplying aBedrockMantleKeyConfig(or a Bearer API key inValue) with the desired region. The region can also be embedded as a prefix in the model ID (e.g.us-west-2/anthropic.claude-haiku-4-5) or set at the alias level viaAliasConfig.Region.Breaking changes
The
signAWSRequestsignature change is internal to thebedrockpackage and does not affect any public API. TheisMantleModelfunction is deprecated but not removed.Security considerations
AWS credentials for
BedrockMantleKeyConfigfollow the sameSecretVarresolution pattern used byBedrockKeyConfig(env-var references, never inlined literals). SigV4 signing is performed per-request on the exact body bytes that are sent, so the signature always covers what is transmitted. When a Bearer API key is present it takes precedence and no AWS credentials are required.Checklist
docs/contributing/README.mdand followed the guidelines