mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-01-04 15:22:29 +08:00
feat: add AWS credentials support for Bedrock provider
- Add AWS Access Key ID, Secret Access Key, Region fields for Bedrock - Show different credential fields based on provider type - Update validation API to handle Bedrock with AWS credentials - Add region selector with common AWS regions
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock"
|
||||||
import { createAnthropic } from "@ai-sdk/anthropic"
|
import { createAnthropic } from "@ai-sdk/anthropic"
|
||||||
import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
|
import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
|
||||||
import { createGateway } from "@ai-sdk/gateway"
|
import { createGateway } from "@ai-sdk/gateway"
|
||||||
@@ -15,12 +16,24 @@ interface ValidateRequest {
|
|||||||
apiKey: string
|
apiKey: string
|
||||||
baseUrl?: string
|
baseUrl?: string
|
||||||
modelId: string
|
modelId: string
|
||||||
|
// AWS Bedrock specific
|
||||||
|
awsAccessKeyId?: string
|
||||||
|
awsSecretAccessKey?: string
|
||||||
|
awsRegion?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
try {
|
try {
|
||||||
const body: ValidateRequest = await req.json()
|
const body: ValidateRequest = await req.json()
|
||||||
const { provider, apiKey, baseUrl, modelId } = body
|
const {
|
||||||
|
provider,
|
||||||
|
apiKey,
|
||||||
|
baseUrl,
|
||||||
|
modelId,
|
||||||
|
awsAccessKeyId,
|
||||||
|
awsSecretAccessKey,
|
||||||
|
awsRegion,
|
||||||
|
} = body
|
||||||
|
|
||||||
if (!provider || !modelId) {
|
if (!provider || !modelId) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -29,8 +42,18 @@ export async function POST(req: Request) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ollama doesn't require API key
|
// Validate credentials based on provider
|
||||||
if (provider !== "ollama" && !apiKey) {
|
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(
|
return NextResponse.json(
|
||||||
{ valid: false, error: "API key is required" },
|
{ valid: false, error: "API key is required" },
|
||||||
{ status: 400 },
|
{ status: 400 },
|
||||||
@@ -76,6 +99,16 @@ export async function POST(req: Request) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "bedrock": {
|
||||||
|
const bedrock = createAmazonBedrock({
|
||||||
|
accessKeyId: awsAccessKeyId,
|
||||||
|
secretAccessKey: awsSecretAccessKey,
|
||||||
|
region: awsRegion,
|
||||||
|
})
|
||||||
|
model = bedrock(modelId)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
case "openrouter": {
|
case "openrouter": {
|
||||||
const openrouter = createOpenRouter({
|
const openrouter = createOpenRouter({
|
||||||
apiKey,
|
apiKey,
|
||||||
|
|||||||
@@ -175,8 +175,15 @@ export function ModelConfigDialog({
|
|||||||
) => {
|
) => {
|
||||||
if (!selectedProviderId) return
|
if (!selectedProviderId) return
|
||||||
updateProvider(selectedProviderId, { [field]: value })
|
updateProvider(selectedProviderId, { [field]: value })
|
||||||
// Reset validation when API key or base URL changes
|
// Reset validation when credentials change
|
||||||
if (field === "apiKey" || field === "baseUrl") {
|
const credentialFields = [
|
||||||
|
"apiKey",
|
||||||
|
"baseUrl",
|
||||||
|
"awsAccessKeyId",
|
||||||
|
"awsSecretAccessKey",
|
||||||
|
"awsRegion",
|
||||||
|
]
|
||||||
|
if (credentialFields.includes(field)) {
|
||||||
setValidationStatus("idle")
|
setValidationStatus("idle")
|
||||||
updateProvider(selectedProviderId, { validated: false })
|
updateProvider(selectedProviderId, { validated: false })
|
||||||
}
|
}
|
||||||
@@ -205,7 +212,21 @@ export function ModelConfigDialog({
|
|||||||
|
|
||||||
// Validate all models
|
// Validate all models
|
||||||
const handleValidate = useCallback(async () => {
|
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
|
// Need at least one model to validate
|
||||||
if (selectedProvider.models.length === 0) {
|
if (selectedProvider.models.length === 0) {
|
||||||
@@ -234,6 +255,10 @@ export function ModelConfigDialog({
|
|||||||
apiKey: selectedProvider.apiKey,
|
apiKey: selectedProvider.apiKey,
|
||||||
baseUrl: selectedProvider.baseUrl,
|
baseUrl: selectedProvider.baseUrl,
|
||||||
modelId: model.modelId,
|
modelId: model.modelId,
|
||||||
|
// AWS Bedrock credentials
|
||||||
|
awsAccessKeyId: selectedProvider.awsAccessKeyId,
|
||||||
|
awsSecretAccessKey: selectedProvider.awsSecretAccessKey,
|
||||||
|
awsRegion: selectedProvider.awsRegion,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -499,136 +524,347 @@ export function ModelConfigDialog({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* API Key */}
|
{/* Credentials - different for Bedrock vs other providers */}
|
||||||
<div className="space-y-2">
|
{selectedProvider.provider ===
|
||||||
<Label
|
"bedrock" ? (
|
||||||
htmlFor="api-key"
|
<>
|
||||||
className="text-xs font-medium flex items-center gap-1.5"
|
{/* AWS Access Key ID */}
|
||||||
>
|
<div className="space-y-2">
|
||||||
<Key className="h-3.5 w-3.5 text-muted-foreground" />
|
<Label
|
||||||
API Key
|
htmlFor="aws-access-key-id"
|
||||||
</Label>
|
className="text-xs font-medium flex items-center gap-1.5"
|
||||||
<div className="flex gap-2">
|
>
|
||||||
<div className="relative flex-1">
|
<Key className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
|
AWS Access Key
|
||||||
|
ID
|
||||||
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="api-key"
|
id="aws-access-key-id"
|
||||||
type={
|
type={
|
||||||
showApiKey
|
showApiKey
|
||||||
? "text"
|
? "text"
|
||||||
: "password"
|
: "password"
|
||||||
}
|
}
|
||||||
value={
|
value={
|
||||||
selectedProvider.apiKey
|
selectedProvider.awsAccessKeyId ||
|
||||||
|
""
|
||||||
}
|
}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleProviderUpdate(
|
handleProviderUpdate(
|
||||||
"apiKey",
|
"awsAccessKeyId",
|
||||||
e.target
|
e.target
|
||||||
.value,
|
.value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
placeholder="Enter your API key"
|
placeholder="AKIA..."
|
||||||
className="h-9 pr-10 font-mono text-xs"
|
className="h-9 font-mono text-xs"
|
||||||
/>
|
/>
|
||||||
<button
|
</div>
|
||||||
type="button"
|
|
||||||
onClick={() =>
|
{/* AWS Secret Access Key */}
|
||||||
setShowApiKey(
|
<div className="space-y-2">
|
||||||
!showApiKey,
|
<Label
|
||||||
|
htmlFor="aws-secret-access-key"
|
||||||
|
className="text-xs font-medium flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<Key className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
|
AWS Secret
|
||||||
|
Access Key
|
||||||
|
</Label>
|
||||||
|
<div className="relative">
|
||||||
|
<Input
|
||||||
|
id="aws-secret-access-key"
|
||||||
|
type={
|
||||||
|
showApiKey
|
||||||
|
? "text"
|
||||||
|
: "password"
|
||||||
|
}
|
||||||
|
value={
|
||||||
|
selectedProvider.awsSecretAccessKey ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(
|
||||||
|
e,
|
||||||
|
) =>
|
||||||
|
handleProviderUpdate(
|
||||||
|
"awsSecretAccessKey",
|
||||||
|
e
|
||||||
|
.target
|
||||||
|
.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="Enter your secret access key"
|
||||||
|
className="h-9 pr-10 font-mono text-xs"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
setShowApiKey(
|
||||||
|
!showApiKey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
>
|
||||||
|
{showApiKey ? (
|
||||||
|
<EyeOff className="h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<Eye className="h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* AWS Region */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label
|
||||||
|
htmlFor="aws-region"
|
||||||
|
className="text-xs font-medium flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<Link2 className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
|
AWS Region
|
||||||
|
</Label>
|
||||||
|
<Select
|
||||||
|
value={
|
||||||
|
selectedProvider.awsRegion ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onValueChange={(
|
||||||
|
v,
|
||||||
|
) =>
|
||||||
|
handleProviderUpdate(
|
||||||
|
"awsRegion",
|
||||||
|
v,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
|
|
||||||
>
|
>
|
||||||
{showApiKey ? (
|
<SelectTrigger className="h-9 font-mono text-xs hover:bg-accent">
|
||||||
<EyeOff className="h-4 w-4" />
|
<SelectValue placeholder="Select region" />
|
||||||
) : (
|
</SelectTrigger>
|
||||||
<Eye className="h-4 w-4" />
|
<SelectContent>
|
||||||
)}
|
<SelectItem value="us-east-1">
|
||||||
</button>
|
us-east-1
|
||||||
|
(N.
|
||||||
|
Virginia)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="us-west-2">
|
||||||
|
us-west-2
|
||||||
|
(Oregon)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="eu-west-1">
|
||||||
|
eu-west-1
|
||||||
|
(Ireland)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="eu-central-1">
|
||||||
|
eu-central-1
|
||||||
|
(Frankfurt)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="ap-northeast-1">
|
||||||
|
ap-northeast-1
|
||||||
|
(Tokyo)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="ap-southeast-1">
|
||||||
|
ap-southeast-1
|
||||||
|
(Singapore)
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="ap-southeast-2">
|
||||||
|
ap-southeast-2
|
||||||
|
(Sydney)
|
||||||
|
</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
|
||||||
variant={
|
|
||||||
validationStatus ===
|
|
||||||
"success"
|
|
||||||
? "outline"
|
|
||||||
: "default"
|
|
||||||
}
|
|
||||||
size="sm"
|
|
||||||
onClick={
|
|
||||||
handleValidate
|
|
||||||
}
|
|
||||||
disabled={
|
|
||||||
!selectedProvider.apiKey ||
|
|
||||||
validationStatus ===
|
|
||||||
"validating"
|
|
||||||
}
|
|
||||||
className={cn(
|
|
||||||
"h-9 px-4",
|
|
||||||
validationStatus ===
|
|
||||||
"success" &&
|
|
||||||
"text-emerald-600 border-emerald-200 dark:border-emerald-800",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{validationStatus ===
|
|
||||||
"validating" ? (
|
|
||||||
<Loader2 className="h-4 w-4 animate-spin" />
|
|
||||||
) : validationStatus ===
|
|
||||||
"success" ? (
|
|
||||||
<>
|
|
||||||
<Check className="h-4 w-4 mr-1.5" />
|
|
||||||
Verified
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
"Test"
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
{validationStatus ===
|
|
||||||
"error" &&
|
|
||||||
validationError && (
|
|
||||||
<p className="text-xs text-destructive flex items-center gap-1">
|
|
||||||
<X className="h-3 w-3" />
|
|
||||||
{
|
|
||||||
validationError
|
|
||||||
}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Base URL */}
|
{/* Test Button for Bedrock */}
|
||||||
<div className="space-y-2">
|
<div className="flex items-center gap-2">
|
||||||
<Label
|
<Button
|
||||||
htmlFor="base-url"
|
variant={
|
||||||
className="text-xs font-medium flex items-center gap-1.5"
|
validationStatus ===
|
||||||
>
|
"success"
|
||||||
<Link2 className="h-3.5 w-3.5 text-muted-foreground" />
|
? "outline"
|
||||||
Base URL
|
: "default"
|
||||||
<span className="text-muted-foreground font-normal">
|
}
|
||||||
(optional)
|
size="sm"
|
||||||
</span>
|
onClick={
|
||||||
</Label>
|
handleValidate
|
||||||
<Input
|
}
|
||||||
id="base-url"
|
disabled={
|
||||||
value={
|
!selectedProvider.awsAccessKeyId ||
|
||||||
selectedProvider.baseUrl ||
|
!selectedProvider.awsSecretAccessKey ||
|
||||||
""
|
!selectedProvider.awsRegion ||
|
||||||
}
|
validationStatus ===
|
||||||
onChange={(e) =>
|
"validating"
|
||||||
handleProviderUpdate(
|
}
|
||||||
"baseUrl",
|
className={cn(
|
||||||
e.target.value,
|
"h-9 px-4",
|
||||||
)
|
validationStatus ===
|
||||||
}
|
"success" &&
|
||||||
placeholder={
|
"text-emerald-600 border-emerald-200 dark:border-emerald-800",
|
||||||
PROVIDER_INFO[
|
)}
|
||||||
selectedProvider
|
>
|
||||||
.provider
|
{validationStatus ===
|
||||||
].defaultBaseUrl ||
|
"validating" ? (
|
||||||
"Custom endpoint URL"
|
<Loader2 className="h-4 w-4 animate-spin" />
|
||||||
}
|
) : validationStatus ===
|
||||||
className="h-9 font-mono text-xs"
|
"success" ? (
|
||||||
/>
|
<>
|
||||||
</div>
|
<Check className="h-4 w-4 mr-1.5" />
|
||||||
|
Verified
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
"Test"
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
{validationStatus ===
|
||||||
|
"error" &&
|
||||||
|
validationError && (
|
||||||
|
<p className="text-xs text-destructive flex items-center gap-1">
|
||||||
|
<X className="h-3 w-3" />
|
||||||
|
{
|
||||||
|
validationError
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{/* API Key */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label
|
||||||
|
htmlFor="api-key"
|
||||||
|
className="text-xs font-medium flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<Key className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
|
API Key
|
||||||
|
</Label>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<div className="relative flex-1">
|
||||||
|
<Input
|
||||||
|
id="api-key"
|
||||||
|
type={
|
||||||
|
showApiKey
|
||||||
|
? "text"
|
||||||
|
: "password"
|
||||||
|
}
|
||||||
|
value={
|
||||||
|
selectedProvider.apiKey
|
||||||
|
}
|
||||||
|
onChange={(
|
||||||
|
e,
|
||||||
|
) =>
|
||||||
|
handleProviderUpdate(
|
||||||
|
"apiKey",
|
||||||
|
e
|
||||||
|
.target
|
||||||
|
.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder="Enter your API key"
|
||||||
|
className="h-9 pr-10 font-mono text-xs"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
setShowApiKey(
|
||||||
|
!showApiKey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
>
|
||||||
|
{showApiKey ? (
|
||||||
|
<EyeOff className="h-4 w-4" />
|
||||||
|
) : (
|
||||||
|
<Eye className="h-4 w-4" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant={
|
||||||
|
validationStatus ===
|
||||||
|
"success"
|
||||||
|
? "outline"
|
||||||
|
: "default"
|
||||||
|
}
|
||||||
|
size="sm"
|
||||||
|
onClick={
|
||||||
|
handleValidate
|
||||||
|
}
|
||||||
|
disabled={
|
||||||
|
!selectedProvider.apiKey ||
|
||||||
|
validationStatus ===
|
||||||
|
"validating"
|
||||||
|
}
|
||||||
|
className={cn(
|
||||||
|
"h-9 px-4",
|
||||||
|
validationStatus ===
|
||||||
|
"success" &&
|
||||||
|
"text-emerald-600 border-emerald-200 dark:border-emerald-800",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{validationStatus ===
|
||||||
|
"validating" ? (
|
||||||
|
<Loader2 className="h-4 w-4 animate-spin" />
|
||||||
|
) : validationStatus ===
|
||||||
|
"success" ? (
|
||||||
|
<>
|
||||||
|
<Check className="h-4 w-4 mr-1.5" />
|
||||||
|
Verified
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
"Test"
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{validationStatus ===
|
||||||
|
"error" &&
|
||||||
|
validationError && (
|
||||||
|
<p className="text-xs text-destructive flex items-center gap-1">
|
||||||
|
<X className="h-3 w-3" />
|
||||||
|
{
|
||||||
|
validationError
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Base URL */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label
|
||||||
|
htmlFor="base-url"
|
||||||
|
className="text-xs font-medium flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
<Link2 className="h-3.5 w-3.5 text-muted-foreground" />
|
||||||
|
Base URL
|
||||||
|
<span className="text-muted-foreground font-normal">
|
||||||
|
(optional)
|
||||||
|
</span>
|
||||||
|
</Label>
|
||||||
|
<Input
|
||||||
|
id="base-url"
|
||||||
|
value={
|
||||||
|
selectedProvider.baseUrl ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleProviderUpdate(
|
||||||
|
"baseUrl",
|
||||||
|
e.target
|
||||||
|
.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
placeholder={
|
||||||
|
PROVIDER_INFO[
|
||||||
|
selectedProvider
|
||||||
|
.provider
|
||||||
|
]
|
||||||
|
.defaultBaseUrl ||
|
||||||
|
"Custom endpoint URL"
|
||||||
|
}
|
||||||
|
className="h-9 font-mono text-xs"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ export interface ProviderConfig {
|
|||||||
name?: string // Custom display name (e.g., "OpenAI Production")
|
name?: string // Custom display name (e.g., "OpenAI Production")
|
||||||
apiKey: string
|
apiKey: string
|
||||||
baseUrl?: string
|
baseUrl?: string
|
||||||
|
// AWS Bedrock specific fields
|
||||||
|
awsAccessKeyId?: string
|
||||||
|
awsSecretAccessKey?: string
|
||||||
|
awsRegion?: string
|
||||||
|
awsSessionToken?: string // Optional, for temporary credentials
|
||||||
models: ModelConfig[]
|
models: ModelConfig[]
|
||||||
validated?: boolean // Has API key been validated
|
validated?: boolean // Has API key been validated
|
||||||
}
|
}
|
||||||
@@ -45,6 +50,11 @@ export interface FlattenedModel {
|
|||||||
providerLabel: string // Provider display name
|
providerLabel: string // Provider display name
|
||||||
apiKey: string
|
apiKey: string
|
||||||
baseUrl?: string
|
baseUrl?: string
|
||||||
|
// AWS Bedrock specific fields
|
||||||
|
awsAccessKeyId?: string
|
||||||
|
awsSecretAccessKey?: string
|
||||||
|
awsRegion?: string
|
||||||
|
awsSessionToken?: string
|
||||||
validated?: boolean // Has this model been validated
|
validated?: boolean // Has this model been validated
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +262,11 @@ export function flattenModels(config: MultiModelConfig): FlattenedModel[] {
|
|||||||
providerLabel,
|
providerLabel,
|
||||||
apiKey: provider.apiKey,
|
apiKey: provider.apiKey,
|
||||||
baseUrl: provider.baseUrl,
|
baseUrl: provider.baseUrl,
|
||||||
|
// AWS Bedrock fields
|
||||||
|
awsAccessKeyId: provider.awsAccessKeyId,
|
||||||
|
awsSecretAccessKey: provider.awsSecretAccessKey,
|
||||||
|
awsRegion: provider.awsRegion,
|
||||||
|
awsSessionToken: provider.awsSessionToken,
|
||||||
validated: model.validated,
|
validated: model.validated,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user