diff --git a/app/api/validate-model/route.ts b/app/api/validate-model/route.ts
index 20633a0..7beeaa4 100644
--- a/app/api/validate-model/route.ts
+++ b/app/api/validate-model/route.ts
@@ -1,3 +1,4 @@
+import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock"
import { createAnthropic } from "@ai-sdk/anthropic"
import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
import { createGateway } from "@ai-sdk/gateway"
@@ -15,12 +16,24 @@ interface ValidateRequest {
apiKey: string
baseUrl?: string
modelId: string
+ // AWS Bedrock specific
+ awsAccessKeyId?: string
+ awsSecretAccessKey?: string
+ awsRegion?: string
}
export async function POST(req: Request) {
try {
const body: ValidateRequest = await req.json()
- const { provider, apiKey, baseUrl, modelId } = body
+ const {
+ provider,
+ apiKey,
+ baseUrl,
+ modelId,
+ awsAccessKeyId,
+ awsSecretAccessKey,
+ awsRegion,
+ } = body
if (!provider || !modelId) {
return NextResponse.json(
@@ -29,8 +42,18 @@ export async function POST(req: Request) {
)
}
- // Ollama doesn't require API key
- if (provider !== "ollama" && !apiKey) {
+ // Validate credentials based on provider
+ if (provider === "bedrock") {
+ if (!awsAccessKeyId || !awsSecretAccessKey || !awsRegion) {
+ return NextResponse.json(
+ {
+ valid: false,
+ error: "AWS credentials (Access Key ID, Secret Access Key, Region) are required",
+ },
+ { status: 400 },
+ )
+ }
+ } else if (provider !== "ollama" && !apiKey) {
return NextResponse.json(
{ valid: false, error: "API key is required" },
{ status: 400 },
@@ -76,6 +99,16 @@ export async function POST(req: Request) {
break
}
+ case "bedrock": {
+ const bedrock = createAmazonBedrock({
+ accessKeyId: awsAccessKeyId,
+ secretAccessKey: awsSecretAccessKey,
+ region: awsRegion,
+ })
+ model = bedrock(modelId)
+ break
+ }
+
case "openrouter": {
const openrouter = createOpenRouter({
apiKey,
diff --git a/components/model-config-dialog.tsx b/components/model-config-dialog.tsx
index de1ba11..c2612e4 100644
--- a/components/model-config-dialog.tsx
+++ b/components/model-config-dialog.tsx
@@ -175,8 +175,15 @@ export function ModelConfigDialog({
) => {
if (!selectedProviderId) return
updateProvider(selectedProviderId, { [field]: value })
- // Reset validation when API key or base URL changes
- if (field === "apiKey" || field === "baseUrl") {
+ // Reset validation when credentials change
+ const credentialFields = [
+ "apiKey",
+ "baseUrl",
+ "awsAccessKeyId",
+ "awsSecretAccessKey",
+ "awsRegion",
+ ]
+ if (credentialFields.includes(field)) {
setValidationStatus("idle")
updateProvider(selectedProviderId, { validated: false })
}
@@ -205,7 +212,21 @@ export function ModelConfigDialog({
// Validate all models
const handleValidate = useCallback(async () => {
- if (!selectedProvider || !selectedProvider.apiKey) return
+ if (!selectedProvider) return
+
+ // Check credentials based on provider type
+ const isBedrock = selectedProvider.provider === "bedrock"
+ if (isBedrock) {
+ if (
+ !selectedProvider.awsAccessKeyId ||
+ !selectedProvider.awsSecretAccessKey ||
+ !selectedProvider.awsRegion
+ ) {
+ return
+ }
+ } else if (!selectedProvider.apiKey) {
+ return
+ }
// Need at least one model to validate
if (selectedProvider.models.length === 0) {
@@ -234,6 +255,10 @@ export function ModelConfigDialog({
apiKey: selectedProvider.apiKey,
baseUrl: selectedProvider.baseUrl,
modelId: model.modelId,
+ // AWS Bedrock credentials
+ awsAccessKeyId: selectedProvider.awsAccessKeyId,
+ awsSecretAccessKey: selectedProvider.awsSecretAccessKey,
+ awsRegion: selectedProvider.awsRegion,
}),
})
@@ -499,136 +524,347 @@ export function ModelConfigDialog({
/>
- {/* API Key */}
-
-
-
-
+ {/* Credentials - different for Bedrock vs other providers */}
+ {selectedProvider.provider ===
+ "bedrock" ? (
+ <>
+ {/* AWS Access Key ID */}
+
+
handleProviderUpdate(
- "apiKey",
+ "awsAccessKeyId",
e.target
.value,
)
}
- placeholder="Enter your API key"
- className="h-9 pr-10 font-mono text-xs"
+ placeholder="AKIA..."
+ className="h-9 font-mono text-xs"
/>
-
+
+ {/* AWS Secret Access Key */}
+
+
+
+
+ handleProviderUpdate(
+ "awsSecretAccessKey",
+ e
+ .target
+ .value,
+ )
+ }
+ placeholder="Enter your secret access key"
+ className="h-9 pr-10 font-mono text-xs"
+ />
+
+
+
+
+ {/* AWS Region */}
+
+
+
-
-
- {validationStatus ===
- "error" &&
- validationError && (
-
-
- {
- validationError
- }
-
- )}
-
- {/* Base URL */}
-
-
-
- handleProviderUpdate(
- "baseUrl",
- e.target.value,
- )
- }
- placeholder={
- PROVIDER_INFO[
- selectedProvider
- .provider
- ].defaultBaseUrl ||
- "Custom endpoint URL"
- }
- className="h-9 font-mono text-xs"
- />
-
+ {/* Test Button for Bedrock */}
+
+
+ {validationStatus ===
+ "error" &&
+ validationError && (
+
+
+ {
+ validationError
+ }
+
+ )}
+
+ >
+ ) : (
+ <>
+ {/* API Key */}
+
+
+
+
+
+ handleProviderUpdate(
+ "apiKey",
+ e
+ .target
+ .value,
+ )
+ }
+ placeholder="Enter your API key"
+ className="h-9 pr-10 font-mono text-xs"
+ />
+
+
+
+
+ {validationStatus ===
+ "error" &&
+ validationError && (
+
+
+ {
+ validationError
+ }
+
+ )}
+
+
+ {/* Base URL */}
+
+
+
+ handleProviderUpdate(
+ "baseUrl",
+ e.target
+ .value,
+ )
+ }
+ placeholder={
+ PROVIDER_INFO[
+ selectedProvider
+ .provider
+ ]
+ .defaultBaseUrl ||
+ "Custom endpoint URL"
+ }
+ className="h-9 font-mono text-xs"
+ />
+
+ >
+ )}
diff --git a/lib/types/model-config.ts b/lib/types/model-config.ts
index 046e95f..fd17250 100644
--- a/lib/types/model-config.ts
+++ b/lib/types/model-config.ts
@@ -26,6 +26,11 @@ export interface ProviderConfig {
name?: string // Custom display name (e.g., "OpenAI Production")
apiKey: string
baseUrl?: string
+ // AWS Bedrock specific fields
+ awsAccessKeyId?: string
+ awsSecretAccessKey?: string
+ awsRegion?: string
+ awsSessionToken?: string // Optional, for temporary credentials
models: ModelConfig[]
validated?: boolean // Has API key been validated
}
@@ -45,6 +50,11 @@ export interface FlattenedModel {
providerLabel: string // Provider display name
apiKey: string
baseUrl?: string
+ // AWS Bedrock specific fields
+ awsAccessKeyId?: string
+ awsSecretAccessKey?: string
+ awsRegion?: string
+ awsSessionToken?: string
validated?: boolean // Has this model been validated
}
@@ -252,6 +262,11 @@ export function flattenModels(config: MultiModelConfig): FlattenedModel[] {
providerLabel,
apiKey: provider.apiKey,
baseUrl: provider.baseUrl,
+ // AWS Bedrock fields
+ awsAccessKeyId: provider.awsAccessKeyId,
+ awsSecretAccessKey: provider.awsSecretAccessKey,
+ awsRegion: provider.awsRegion,
+ awsSessionToken: provider.awsSessionToken,
validated: model.validated,
})
}