Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Usage } from '@anthropic-ai/sdk/resources/messages'
export class AwsBedrockProvider extends BaseLLMProvider {
private bedrock!: BedrockClient
private bedrockRuntime!: BedrockRuntimeClient
private defaultModel = 'claude-3-7-sonnet-20250219'
private defaultModel = 'anthropic.claude-3-5-sonnet-20240620-v1:0'

constructor(provider: AWS_BEDROCK_PROVIDER, configPresenter: ConfigPresenter) {
super(provider, configPresenter)
Expand All @@ -43,10 +43,8 @@ export class AwsBedrockProvider extends BaseLLMProvider {
provider.credential?.secretAccessKey || process.env.BEDROCK_SECRET_ACCESS_KEY
const region = provider.credential?.region || process.env.BEDROCK_REGION

if (!accessKeyId || !secretAccessKey) {
throw new Error(
'apiKey must be provided as "${ACCESS_KEY_ID}:${SECRET_ACCESS_KEY}" format.'
)
if (!accessKeyId || !secretAccessKey || !region) {
throw new Error('Access Key Id, Secret Access Key and Region are all needed.')
}

this.bedrock = new BedrockClient({
Expand All @@ -68,19 +66,18 @@ export class AwsBedrockProvider extends BaseLLMProvider {

protected async fetchProviderModels(): Promise<MODEL_META[]> {
try {
const region = await this.bedrock.config.region()
const command = new ListFoundationModelsCommand({})
const response = await this.bedrock.send(command)
const models = response.modelSummaries

return (
models
?.filter((m) => m.modelId?.includes('anthropic.claude'))
?.filter((m) => m.modelId && /^anthropic.claude-[a-z0-9\-]+(:\d+)$/g.test(m.modelId))
?.filter((m) => m.modelLifecycle?.status === 'ACTIVE')
?.filter((m) => m.inferenceTypesSupported && m.inferenceTypesSupported.length > 0)
.map<MODEL_META>((m) => ({
// id: m.modelId!,
// id: m.modelArn!,
id: `${m.inferenceTypesSupported?.includes('ON_DEMAND') ? m.modelId! : `us.${m.modelId}`}`,
// name: `${m.modelName} (${m.modelId})`,
id: `${m.inferenceTypesSupported?.includes('ON_DEMAND') ? m.modelId! : `${region.split('-')[0]}.${m.modelId}`}`,
name: m.modelId?.replace('anthropic.', '') || '<Unknown>',
providerId: this.provider.id,
maxTokens: 64_000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<Input
:id="`${provider.id}-accessKeyId`"
:model-value="accessKeyId"
type="password"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Placeholders/labels mismatch and i18n usage verification

  • Using urlPlaceholder for credentials/region is confusing; fixed above.
  • “bedrockLimitTip” is correctly localized. Once you add new AWS i18n keys, verify all locales are present to avoid missing-translation UI glitches.

Run this to validate:

Also applies to: 26-26, 34-35, 69-69


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Check bedrockVerifyTip exists in all locales"
rg -n '"bedrockVerifyTip"' src/renderer/src/i18n -C1

echo "Find hardcoded AWS labels still present in renderer"
rg -nP 'AWS (Access Key Id|Secret Access Key|Region)' src/renderer/src -g '!**/node_modules/**' -C2

echo "Find non-English (CJK) logs/comments in renderer code"
rg -nP '[\p{Han}]' src/renderer/src -g '!**/node_modules/**' -C2

Length of output: 274635


Replace Hardcoded AWS Labels with i18n Keys

  • Confirmed bedrockVerifyTip exists in all locales.
  • In src/renderer/src/components/settings/BedrockProviderSettingsDetail.vue, replace the hardcoded AWS labels/placeholder misuse with dedicated i18n keys:
    • Line 7: change
    <Label …>AWS Access Key Id</Label>
    {{ t('settings.provider.awsAccessKeyId') }}
    • Line 21: change
    <Label …>AWS Secret Access Key</Label>
    {{ t('settings.provider.awsSecretAccessKey') }}
    • Line 34: change
    <Label …>AWS Region</Label>
    {{ t('settings.provider.awsRegion') }}
    • For each <Input> under those labels, replace urlPlaceholder with :placeholder="t('settings.provider.awsAccessKeyIdPlaceholder')" (and likewise for secretAccessKeyPlaceholder / regionPlaceholder).
  • Define the following new keys (and placeholder variants) under settings.provider in every locale’s settings.json to ensure full coverage:
    • awsAccessKeyId
    • awsAccessKeyIdPlaceholder
    • awsSecretAccessKey
    • awsSecretAccessKeyPlaceholder
    • awsRegion
    • awsRegionPlaceholder
  • Remove or translate all remaining non-English (CJK) comments/logs in the renderer code to maintain consistency.
🤖 Prompt for AI Agents
In src/renderer/src/components/settings/BedrockProviderSettingsDetail.vue around
lines 7, 12, 21, 34, replace the hardcoded label text "AWS Access Key Id", "AWS
Secret Access Key" and "AWS Region" with i18n lookups (e.g. use
t('settings.provider.awsAccessKeyId'),
t('settings.provider.awsSecretAccessKey'), t('settings.provider.awsRegion')),
and update each corresponding <Input> to use
:placeholder="t('settings.provider.awsAccessKeyIdPlaceholder')" (and the
secret/region placeholder keys respectively) instead of the current
urlPlaceholder; then add the six new keys (awsAccessKeyId,
awsAccessKeyIdPlaceholder, awsSecretAccessKey, awsSecretAccessKeyPlaceholder,
awsRegion, awsRegionPlaceholder) under settings.provider in every locale's
settings.json, and remove or translate any remaining non-English (CJK)
comments/logs in the renderer code for consistency.

:placeholder="t('settings.provider.urlPlaceholder')"
@blur="handleAccessKeyIdChange(String($event.target.value))"
@keyup.enter="handleAccessKeyIdChange(accessKeyId)"
Expand All @@ -22,6 +23,7 @@
<Input
:id="`${provider.id}-secretAccessKey`"
:model-value="secretAccessKey"
type="password"
:placeholder="t('settings.provider.urlPlaceholder')"
@blur="handleSecretAccessKeyChange(String($event.target.value))"
@keyup.enter="handleSecretAccessKeyChange(secretAccessKey)"
Expand Down Expand Up @@ -52,6 +54,16 @@
t('settings.provider.verifyKey')
}}
</Button>
<TooltipProvider :delayDuration="200">
<Tooltip>
<TooltipTrigger>
<Icon icon="lucide:help-circle" class="w-4 h-4 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent>
<p>{{ t('settings.provider.bedrockVerifyTip') }}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>

<div class="hint">{{ t('settings.provider.bedrockLimitTip') }}</div>
Expand Down Expand Up @@ -98,6 +110,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import { Label } from '@/components/ui/label'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { Icon } from '@iconify/vue'
import ProviderModelManager from './ProviderModelManager.vue'
import ProviderDialogContainer from './ProviderDialogContainer.vue'
Expand Down Expand Up @@ -204,27 +217,23 @@ const validateCredential = async () => {
const resp = await settingsStore.checkProvider(props.provider.id)
if (resp.isOk) {
console.log('验证成功')
// checkResult.value = true
checkResult.value = true
showCheckModelDialog.value = true
// 验证成功后刷新当前provider的模型列表
await settingsStore.refreshProviderModels(props.provider.id)
} else {
console.log('验证失败', resp.errorMsg)
// checkResult.value = false
checkResult.value = false
showCheckModelDialog.value = true
}
} catch (error) {
console.error('Failed to validate credential:', error)
// checkResult.value = false
checkResult.value = false
showCheckModelDialog.value = true
}
}

const handleVerifyCredential = async (updates: Partial<AWS_BEDROCK_PROVIDER>) => {
// const inputElement = document.getElementById(`${props.provider.id}-apikey`)
// if (inputElement) {
// inputElement.blur()
// }
await settingsStore.updateAwsBedrockProviderConfig(props.provider.id, updates)
await validateCredential()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
@auth-error="handleAnthropicAuthError"
/>
<BedrockProviderSettingsDetail
v-else-if="activeProvider.apiType === 'bedrock'"
v-else-if="activeProvider.apiType === 'aws-bedrock'"
:key="`bedrock-${activeProvider.id}`"
:provider="activeProvider as AWS_BEDROCK_PROVIDER"
class="flex-1"
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/en-US/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "Operation failed",
"operationSuccess": "Operation is successful",
"settingsApplied": "Settings applied",
"bedrockLimitTip": "* Only Anthropic Claude supported (including Opus, Sonnet, Haiku models)"
"bedrockLimitTip": "* Only Anthropic Claude supported (including Opus, Sonnet, Haiku models)",
"bedrockVerifyTip": "DeepChat uses Claude 3.5 Sonnet for verification. If you do not have permission to invoke, the verification will fail. This will not affect the use of other models."
},
"knowledgeBase": {
"title": "Knowledge Base Settings",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/fa-IR/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "عملیات شکست خورد",
"operationSuccess": "عملیات موفقیت آمیز است",
"settingsApplied": "تنظیمات اعمال شده",
"bedrockLimitTip": "* فقط از Anthropic Claude (شامل مدل‌های Opus، Sonnet، Haiku) پشتیبانی می‌کند"
"bedrockLimitTip": "* فقط از Anthropic Claude (شامل مدل‌های Opus، Sonnet، Haiku) پشتیبانی می‌کند",
"bedrockVerifyTip": "DeepChat از Claude 3.5 Sonnet برای تأیید استفاده می‌کند. اگر مجوز فراخوانی نداشته باشید، تأیید انجام نخواهد شد. این موضوع تاثیری بر استفاده از مدل‌های دیگر نخواهد داشت."
},
"knowledgeBase": {
"title": "تنظیمات پایگاه دانش",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/fr-FR/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "L'opération a échoué",
"operationSuccess": "L'opération est réussie",
"settingsApplied": "Paramètres appliqués",
"bedrockLimitTip": "* Prend uniquement en charge Anthropic Claude (y compris les modèles Opus, Sonnet, Haiku)"
"bedrockLimitTip": "* Prend uniquement en charge Anthropic Claude (y compris les modèles Opus, Sonnet, Haiku)",
"bedrockVerifyTip": "DeepChat utilise Claude 3.5 Sonnet pour la vérification. Si vous n'avez pas l'autorisation de l'invoquer, la vérification échouera. Cela n'affectera pas l'utilisation des autres modèles."
},
"knowledgeBase": {
"title": "Paramètres de la base de connaissances",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/ja-JP/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "操作に失敗しました",
"operationSuccess": "操作は成功しました",
"settingsApplied": "適用された設定",
"bedrockLimitTip": "* Anthropic Claude(Opus、Sonnet、Haikuモデルを含む)のみをサポート"
"bedrockLimitTip": "* Anthropic Claude(Opus、Sonnet、Haikuモデルを含む)のみをサポート",
"bedrockVerifyTip": "DeepChatは検証にClaude 3.5 Sonnetを使用しています。起動権限がない場合、検証は失敗します。ただし、他のモデルの使用には影響しません。"
},
"knowledgeBase": {
"title": "ナレッジベース設定",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/ko-KR/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "작동 실패",
"operationSuccess": "운영이 성공적입니다",
"settingsApplied": "설정이 적용됩니다",
"bedrockLimitTip": "* Anthropic Claude(Opus, Sonnet, Haiku 모델 포함)만 지원합니다."
"bedrockLimitTip": "* Anthropic Claude(Opus, Sonnet, Haiku 모델 포함)만 지원합니다.",
"bedrockVerifyTip": "DeepChat은 검증을 위해 Claude 3.5 Sonnet을 사용합니다. 호출 권한이 없으면 검증이 실패합니다. 이는 다른 모델 사용에는 영향을 미치지 않습니다."
},
"knowledgeBase": {
"title": "지식 베이스 설정",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/ru-RU/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "Операция не удалась",
"operationSuccess": "Операция успешна",
"settingsApplied": "Применяются настройки",
"bedrockLimitTip": "* Поддерживает только Anthropic Claude (включая модели Opus, Sonnet, Haiku)"
"bedrockLimitTip": "* Поддерживает только Anthropic Claude (включая модели Opus, Sonnet, Haiku)",
"bedrockVerifyTip": "DeepChat использует модель Claude 3.5 Sonnet для верификации. Если у вас нет разрешения на её использование, верификация не пройдёт. Это не повлияет на использование других моделей."
},
"knowledgeBase": {
"title": "Настройки базы знаний",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/zh-CN/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"anthropicOAuthActiveTip": "OAuth 认证已启用,您可以直接使用 Anthropic 服务",
"oauthVerifySuccess": "OAuth 连接验证成功",
"oauthVerifyFailed": "OAuth 连接验证失败",
"bedrockLimitTip": "* 仅支持 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)"
"bedrockLimitTip": "* 仅支持 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)",
"bedrockVerifyTip": "DeepChat 使用 Claude 3.5 Sonnet 模型验证,若您无此模型的调用权限验证将失败。这不会影响其他模型的使用。"
},
"knowledgeBase": {
"title": "知识库设置",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/zh-HK/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "操作失敗",
"operationSuccess": "操作成功",
"settingsApplied": "設置已應用",
"bedrockLimitTip": "* 僅支持 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)"
"bedrockLimitTip": "* 僅支持 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)",
"bedrockVerifyTip": "DeepChat 使用 Claude 3.5 Sonnet 模型驗證,若您無此模型的調用權限驗證將失敗。這不會影響其他模型的使用。"
},
"knowledgeBase": {
"fastgptTitle": "FastGPT知識庫",
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/src/i18n/zh-TW/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@
"operationFailed": "操作失敗",
"operationSuccess": "操作成功",
"settingsApplied": "設置已應用",
"bedrockLimitTip": "* 僅支援 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)"
"bedrockLimitTip": "* 僅支援 Anthropic Claude(包括 Opus,Sonnet,Haiku 模型)",
"bedrockVerifyTip": "DeepChat 使用 Claude 3.5 Sonnet 模型驗證,若您無此模型的呼叫許可權驗證將失敗。這不會影響其他模型的使用。"
},
"knowledgeBase": {
"title": "知識庫設置",
Expand Down