Skip to content

feat(channel): add AWS OpenAI support for Amazon Bedrock - #6340

Draft
gorquan wants to merge 1 commit into
QuantumNous:mainfrom
gorquan:agent/add-aws-openai-bedrock-channel
Draft

feat(channel): add AWS OpenAI support for Amazon Bedrock#6340
gorquan wants to merge 1 commit into
QuantumNous:mainfrom
gorquan:agent/add-aws-openai-bedrock-channel

Conversation

@gorquan

@gorquan gorquan commented Jul 20, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 本描述根据实际代码、AWS 官方接口行为和本地验证结果整理;实现过程使用了 OpenAI Codex 辅助。

📝 变更描述 / Description

新增独立的 AWS OpenAI 渠道类型(type 59),用于调用 Amazon Bedrock 上的 OpenAI 模型。

现有 AWS 渠道通过 Bedrock InvokeModel 转换 Claude 等原生请求,无法直接调用仅开放 OpenAI-compatible Responses API 的 GPT-5.4、GPT-5.5 和 GPT-5.6。此实现复用现有 OpenAI adaptor,同时补充 Bedrock 所需的认证、端点选择和 API 路由:

  • 支持 AccessKey|SecretAccessKey|Region,对最终 HTTP 请求执行 AWS SigV4 签名。
  • 支持 Bedrock API Key,输入格式为 APIKey|Region
  • Base URL 可留空,由 Region 和模型自动选择 bedrock-mantlebedrock-runtime
  • GPT-5.4、GPT-5.5、GPT-5.6 自动使用 Mantle 的 /openai/v1/responses
  • Mantle gpt-oss 支持 Chat Completions 和 Responses;Runtime 版本模型使用 Chat Completions。
  • 当兼容客户端使用 /v1/chat/completions 调用 Responses-only 模型时,强制执行 Chat → Responses 转换,包括开启完整请求透传的场景。
  • SigV4 在 Header Override 应用后执行,确保签名覆盖最终发送的 Host 和 Headers。
  • 补充渠道测试端点选择、模型元数据、计费倍率、缓存倍率、前端配置和多语言提示。

相比 #5375,本实现基于当前 main:使用未被占用的 type 59,支持 AK/SK SigV4 与 API Key 两种认证、Region 自动拼接端点,并按 AWS 当前模型/API 兼容矩阵区分 Mantle Responses、Mantle Chat 和 Runtime Chat。

本代码由 gorquan 使用 OpenAI Codex 辅助实现和审查。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。(Draft 阶段,提交者仍需最终人工确认)
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。(已发现 feat: add Bedrock OpenAI channel type for GPT-5.5/5.4 #5375;本 PR 是解决 type 冲突、认证和端点处理问题的替代实现)
  • Bug fix 说明: 本 PR 标记为 New feature,不按 Bug fix 提交。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

  • go test ./...
  • bun run typecheck
  • bun run format:check
  • 对所有改动的 JS/TS/TSX 文件运行 oxlint ✅(仅有既有 warning,无 error)
  • bun run i18n:sync ✅,运行后工作区无额外变更
  • bun run build
  • git diff --check
  • bun run copyright:check ⚠️ 当前 main 的全仓基线会报告约 1009 个文件需要版权头更新;本 PR 未批量修改这些无关文件。
  • AWS 实际请求 E2E 未执行:当前没有可用的 Bedrock 凭证;端点、认证和模型矩阵按 AWS 官方文档实现,并由单元测试覆盖。

Summary by CodeRabbit

  • New Features

    • Added AWS OpenAI as a supported channel through Amazon Bedrock.
    • Added support for API key and AWS access-key authentication.
    • Added automatic endpoint selection for chat and responses models.
    • Added AWS OpenAI models to model listings and configuration options.
    • Added streaming support and request signing for AWS-authenticated requests.
    • Added channel setup guidance, warnings, icons, and translations.
  • Bug Fixes

    • Improved responses-mode routing and endpoint detection for supported models.
    • Added model-specific ratio configuration for newly supported models.
  • Tests

    • Added coverage for model classification, endpoints, authentication, signing, and channel configuration.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds AWS OpenAI support for Bedrock, including model classification, endpoint construction, AWS credential handling and SigV4 signing, Responses routing, model registration, ratio defaults, and channel configuration UI updates.

Changes

AWS OpenAI Bedrock integration

Layer / File(s) Summary
Channel and model contracts
common/..., constant/channel.go
Defines channel type 59, model classifications and normalization helpers, API mapping, and endpoint metadata for Bedrock OpenAI models.
Bedrock adapter and request signing
relay/channel/...
Constructs Bedrock Runtime and Mantle URLs, parses credentials, signs AK/SK requests, supports API keys, preserves request bodies, and exposes Bedrock model metadata.
Relay endpoint and Responses routing
service/..., relay/..., controller/...
Selects Responses mode for eligible Bedrock models, normalizes mapped test endpoints, and enables streaming options.
Model registration and ratios
controller/model.go, setting/ratio_setting/...
Registers Bedrock OpenAI models and adds model, completion, cache, and creation-cache ratios.
Channel configuration UI
web/src/features/channels/..., web/src/i18n/locales/*, web/scripts/sync-i18n.mjs
Adds channel 59 to UI configuration, credential forms, hints, warnings, icons, translations, and i18n synchronization.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Relay
  participant OpenAIAdaptor
  participant Bedrock
  Client->>Relay: Submit OpenAI-compatible request
  Relay->>OpenAIAdaptor: Convert request and resolve endpoint
  OpenAIAdaptor->>Bedrock: Send API-key or SigV4-authenticated request
  Bedrock-->>Relay: Return model response
  Relay-->>Client: Return OpenAI-compatible response
Loading

Possibly related PRs

Suggested reviewers: calcium-ion

Poem

I’m a rabbit with AWS keys,
Signing requests through woodland trees.
Mantle or Runtime, paths align,
GPT models hop in line.
“AWS OpenAI!” we cheer—
Responses mode is finally here!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also adds broader AWS OpenAI UI, locale, and GPT-5.6/gpt-oss support beyond the linked GPT-5.4/5.5 request. Split the GPT-5.4/5.5 fix from the broader AWS OpenAI channel, UI, locale, and extra model support, or link an issue that covers that scope.
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes adding AWS OpenAI support for Amazon Bedrock.
Linked Issues check ✅ Passed The PR adds Bedrock support for GPT-5.4 and GPT-5.5, matching the linked issue's request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (ai_padded_prose). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
controller/channel_test_internal_test.go (1)

221-233: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use testify/assert for non-fatal assertions in new tests.

As per coding guidelines, new or substantially rewritten Go backend tests must use testify/require strictly for setup and fatal assertions, and testify/assert for non-fatal checks. Please update the final result assertions across these test files to use assert. Also, ensure github.com/stretchr/testify/assert is added to the imports if not already present.

  • controller/channel_test_internal_test.go#L221-L233: Replace require.Equal and require.Empty with assert.Equal and assert.Empty for checking the endpoint return values.
  • service/openai_chat_responses_mode_test.go#L23-L35: Replace the require.True and require.False output verifications with assert.True and assert.False.
  • controller/model_owned_by_test.go#L68-L68: Replace require.Equal with assert.Equal for checking the OwnedBy result.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controller/channel_test_internal_test.go` around lines 221 - 233, Replace
non-fatal result assertions with testify/assert: in
controller/channel_test_internal_test.go lines 221-233, use assert.Equal and
assert.Empty; in service/openai_chat_responses_mode_test.go lines 23-35, use
assert.True and assert.False; and in controller/model_owned_by_test.go line 68,
use assert.Equal. Add the assert import where missing, while retaining require
for setup and fatal assertions.

Source: Coding guidelines

web/src/features/channels/components/drawers/channel-mutate-drawer.tsx (1)

2909-2946: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider extracting the repeated AWS-type check.

[33, 59].includes(currentType) is repeated four times in this branch chain. Extracting a local const isAwsChannel = [33, 59].includes(currentType) before the branches would reduce duplication and make future edits (e.g., adding a third AWS-like type) less error-prone.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/features/channels/components/drawers/channel-mutate-drawer.tsx`
around lines 2909 - 2946, In the placeholder-selection branch, define a local
isAwsChannel boolean from [33, 59].includes(currentType) before the conditional
chain, then replace all four repeated AWS-type checks with that variable while
preserving the existing branch order and behavior.
relay/channel/openai/bedrock_openai.go (1)

126-170: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Signing region is never reconciled against an explicit ChannelBaseUrl's embedded region.

getBedrockOpenAIRequestURL uses info.ChannelBaseUrl verbatim when it's set, but SignRequest always signs with credentials.region parsed from the ApiKey string. If an admin sets an explicit base URL for one region (e.g. bedrock-mantle.us-west-2.api.aws) while the credential string encodes a different region, every request will fail AWS's SigV4 signature check with a confusing region/signature mismatch, since AWS requires the signing scope to exactly match the endpoint's region.

Deriving the region from a recognized bedrock-mantle/bedrock-runtime hostname (falling back to credentials.region only for custom/proxy base URLs) — or at least validating the two agree — would turn this into a clear config-time error instead of an opaque upstream 403.

♻️ Suggested approach
// regionFromBedrockHostname extracts the region segment from recognized
// bedrock-mantle/bedrock-runtime hostnames so SigV4 always signs for the
// region actually being called.
func regionFromBedrockHostname(hostname string) (string, bool) {
	hostname = strings.ToLower(hostname)
	switch {
	case strings.HasPrefix(hostname, "bedrock-mantle.") && strings.HasSuffix(hostname, ".api.aws"):
		return strings.TrimSuffix(strings.TrimPrefix(hostname, "bedrock-mantle."), ".api.aws"), true
	case strings.HasPrefix(hostname, "bedrock-runtime."):
		trimmed := strings.TrimSuffix(strings.TrimPrefix(hostname, "bedrock-runtime."), ".amazonaws.com.cn")
		trimmed = strings.TrimSuffix(trimmed, ".amazonaws.com")
		return trimmed, true
	}
	return "", false
}

Then in SignRequest, prefer the URL-derived region (or error on mismatch) before falling back to credentials.region.

Also applies to: 206-236

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/channel/openai/bedrock_openai.go` around lines 126 - 170, Reconcile the
SigV4 signing region with explicit Bedrock endpoint URLs: add a hostname-region
helper for recognized bedrock-mantle and bedrock-runtime hosts, then update
SignRequest to use the URL-derived region or return a clear mismatch error when
it differs from credentials.region. Preserve credentials.region as the fallback
for custom or proxy URLs, and ensure getBedrockOpenAIRequestURL validation
remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/features/channels/constants.ts`:
- Around line 395-402: Update the type-59 key prompt returned by
getKeyPromptForType to advertise both supported AWS credential formats, or
select the correct format based on aws_key_type. Add and use matching locale
keys for the new user-facing text so the prompt remains fully internationalized.

In `@web/src/i18n/locales/ru.json`:
- Line 247: Update the AWS endpoint guidance source string and its locale
translations to state that endpoint generation depends on both the selected
model and Region, while preserving the existing AK/SK and API Key format
details.

In `@web/src/i18n/locales/zh.json`:
- Around line 246-247: Update the AWS endpoint hint translation entry in the
locale source and all corresponding locale translations to state that endpoint
selection is generated from both Region and model, while preserving the existing
AK/SK and API Key credential guidance.

---

Nitpick comments:
In `@controller/channel_test_internal_test.go`:
- Around line 221-233: Replace non-fatal result assertions with testify/assert:
in controller/channel_test_internal_test.go lines 221-233, use assert.Equal and
assert.Empty; in service/openai_chat_responses_mode_test.go lines 23-35, use
assert.True and assert.False; and in controller/model_owned_by_test.go line 68,
use assert.Equal. Add the assert import where missing, while retaining require
for setup and fatal assertions.

In `@relay/channel/openai/bedrock_openai.go`:
- Around line 126-170: Reconcile the SigV4 signing region with explicit Bedrock
endpoint URLs: add a hostname-region helper for recognized bedrock-mantle and
bedrock-runtime hosts, then update SignRequest to use the URL-derived region or
return a clear mismatch error when it differs from credentials.region. Preserve
credentials.region as the fallback for custom or proxy URLs, and ensure
getBedrockOpenAIRequestURL validation remains unchanged.

In `@web/src/features/channels/components/drawers/channel-mutate-drawer.tsx`:
- Around line 2909-2946: In the placeholder-selection branch, define a local
isAwsChannel boolean from [33, 59].includes(currentType) before the conditional
chain, then replace all four repeated AWS-type checks with that variable while
preserving the existing branch order and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 334b4959-2aba-467d-96ac-135ec7ba4833

📥 Commits

Reviewing files that changed from the base of the PR and between 4aa08f9 and ff37a43.

📒 Files selected for processing (34)
  • common/api_type.go
  • common/bedrock_openai_test.go
  • common/endpoint_type.go
  • common/model.go
  • constant/channel.go
  • controller/channel-test.go
  • controller/channel_test_internal_test.go
  • controller/model.go
  • controller/model_owned_by_test.go
  • relay/channel/adapter.go
  • relay/channel/api_request.go
  • relay/channel/openai/adaptor.go
  • relay/channel/openai/bedrock_openai.go
  • relay/channel/openai/bedrock_openai_test.go
  • relay/claude_handler.go
  • relay/common/relay_info.go
  • relay/compatible_handler.go
  • service/openai_chat_responses_mode.go
  • service/openai_chat_responses_mode_test.go
  • setting/ratio_setting/cache_ratio.go
  • setting/ratio_setting/model_ratio.go
  • web/scripts/sync-i18n.mjs
  • web/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/src/features/channels/constants.ts
  • web/src/features/channels/lib/channel-form.ts
  • web/src/features/channels/lib/channel-type-config.ts
  • web/src/features/channels/lib/channel-utils.ts
  • web/src/i18n/locales/en.json
  • web/src/i18n/locales/fr.json
  • web/src/i18n/locales/ja.json
  • web/src/i18n/locales/ru.json
  • web/src/i18n/locales/vi.json
  • web/src/i18n/locales/zh-TW.json
  • web/src/i18n/locales/zh.json

Comment on lines +395 to +402
59: 'Format: AccessKey|SecretAccessKey|Region',
}

export const CHANNEL_TYPE_WARNINGS: Record<number, string> = {
3: 'For channels added after May 10, 2025, no need to remove "." from model names during deployment',
8: 'If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing',
37: 'Dify channels only support chatflow and agent, and agent does not support images',
59: 'The AWS endpoint is generated from Region. AK/SK mode uses AccessKey|SecretAccessKey|Region; API Key mode uses APIKey|Region.',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Show both supported credential formats in the key prompt.

getKeyPromptForType(59) is used as the key placeholder, but this prompt only advertises AccessKey|SecretAccessKey|Region. Type 59 also supports APIKey|Region, so API-key users receive misleading instructions. Make the prompt conditional on aws_key_type or include both formats, with matching locale keys.

As per coding guidelines, user-facing web text must support i18n.

Proposed fix
-  59: 'Format: AccessKey|SecretAccessKey|Region',
+  59: 'Format: AccessKey|SecretAccessKey|Region or APIKey|Region',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
59: 'Format: AccessKey|SecretAccessKey|Region',
}
export const CHANNEL_TYPE_WARNINGS: Record<number, string> = {
3: 'For channels added after May 10, 2025, no need to remove "." from model names during deployment',
8: 'If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing',
37: 'Dify channels only support chatflow and agent, and agent does not support images',
59: 'The AWS endpoint is generated from Region. AK/SK mode uses AccessKey|SecretAccessKey|Region; API Key mode uses APIKey|Region.',
59: 'Format: AccessKey|SecretAccessKey|Region or APIKey|Region',
}
export const CHANNEL_TYPE_WARNINGS: Record<number, string> = {
3: 'For channels added after May 10, 2025, no need to remove "." from model names during deployment',
8: 'If connecting to upstream One API or New API relay projects, use OpenAI type instead unless you know what you are doing',
37: 'Dify channels only support chatflow and agent, and agent does not support images',
59: 'The AWS endpoint is generated from Region. AK/SK mode uses AccessKey|SecretAccessKey|Region; API Key mode uses APIKey|Region.',
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/features/channels/constants.ts` around lines 395 - 402, Update the
type-59 key prompt returned by getKeyPromptForType to advertise both supported
AWS credential formats, or select the correct format based on aws_key_type. Add
and use matching locale keys for the new user-facing text so the prompt remains
fully internationalized.

Source: Coding guidelines

"Advanced Configuration": "Расширенная конфигурация",
"Advanced Custom": "Расширенный пользовательский",
"AWS OpenAI": "AWS OpenAI",
"The AWS endpoint is generated from Region. AK/SK mode uses AccessKey|SecretAccessKey|Region; API Key mode uses APIKey|Region.": "Конечная точка AWS создаётся из Region. Режим AK/SK использует AccessKey|SecretAccessKey|Region; режим API Key использует APIKey|Region.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Mention model-based endpoint selection.

This guidance says the AWS endpoint is generated only from Region, but endpoint selection also depends on the model. Update the source string and locale translations so users do not assume changing only the region is sufficient.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/i18n/locales/ru.json` at line 247, Update the AWS endpoint guidance
source string and its locale translations to state that endpoint generation
depends on both the selected model and Region, while preserving the existing
AK/SK and API Key format details.

Comment on lines +246 to +247
"AWS OpenAI": "AWS OpenAI",
"The AWS endpoint is generated from Region. AK/SK mode uses AccessKey|SecretAccessKey|Region; API Key mode uses APIKey|Region.": "AWS 端点将根据 Region 自动生成。AK/SK 模式使用 AccessKey|SecretAccessKey|Region;API Key 模式使用 APIKey|Region。",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Mention that endpoint selection also depends on the model

The hint currently says the AWS endpoint is generated only from Region, but this channel selects Mantle versus Runtime endpoints based on both region and model. Update the source string and locale translations so users are not given incomplete routing guidance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/i18n/locales/zh.json` around lines 246 - 247, Update the AWS endpoint
hint translation entry in the locale source and all corresponding locale
translations to state that endpoint selection is generated from both Region and
model, while preserving the existing AK/SK and API Key credential guidance.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

请求添加对AWS Bedrock:GPT-5.5、GPT-5.4的支持

1 participant