mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
ui refactor
This commit is contained in:
parent
b82c7994df
commit
6cf0e7c27e
4 changed files with 289 additions and 235 deletions
|
|
@ -1,29 +1,15 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Modal, Checkbox, Button, Divider, Tag, Select, Switch, Tooltip } from "antd";
|
||||
import { Modal, Checkbox, Button, Divider, Tag, Tooltip } from "antd";
|
||||
import { CheckCircleOutlined, InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { credentialListCall } from "../networking";
|
||||
import PartnerGuardrailCard from "./partner_guardrail_card";
|
||||
import {
|
||||
GuardrailInfo,
|
||||
PartnerGuardrailConfig,
|
||||
PartnerGuardrailSelection,
|
||||
} from "./types";
|
||||
|
||||
interface GuardrailInfo {
|
||||
guardrail_name: string;
|
||||
description: string;
|
||||
alreadyExists: boolean;
|
||||
definition: any;
|
||||
}
|
||||
|
||||
interface PartnerGuardrailConfig {
|
||||
provider: string;
|
||||
label: string;
|
||||
description: string;
|
||||
credential_provider: string;
|
||||
provision_config: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface PartnerGuardrailSelection {
|
||||
provider: string;
|
||||
credential_name: string;
|
||||
provision_config: Record<string, any>;
|
||||
aws_region_name?: string;
|
||||
}
|
||||
export type { PartnerGuardrailSelection } from "./types";
|
||||
|
||||
interface GuardrailSelectionModalProps {
|
||||
visible: boolean;
|
||||
|
|
@ -39,181 +25,6 @@ interface GuardrailSelectionModalProps {
|
|||
accessToken?: string;
|
||||
}
|
||||
|
||||
const AWS_REGIONS = [
|
||||
"us-east-1",
|
||||
"us-east-2",
|
||||
"us-west-2",
|
||||
"eu-west-1",
|
||||
"eu-west-2",
|
||||
"eu-central-1",
|
||||
"ap-southeast-1",
|
||||
"ap-southeast-2",
|
||||
"ap-northeast-1",
|
||||
];
|
||||
|
||||
const partnerProviderLogoMap: Record<string, string> = {
|
||||
bedrock: "../ui/assets/logos/bedrock.svg",
|
||||
};
|
||||
|
||||
const ProviderLogo: React.FC<{ provider: string }> = ({ provider }) => {
|
||||
const logoSrc = partnerProviderLogoMap[provider];
|
||||
if (logoSrc) {
|
||||
return (
|
||||
<img
|
||||
src={logoSrc}
|
||||
alt={provider}
|
||||
style={{ height: "20px", width: "20px", objectFit: "contain" }}
|
||||
onError={(e) => { e.currentTarget.style.display = "none"; }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="w-5 h-5 rounded bg-gray-200 flex items-center justify-center text-xs font-bold text-gray-500">
|
||||
?
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ProvisionConfigTags: React.FC<{ config: Record<string, any> }> = ({ config }) => (
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{config.topicPolicyConfig && (
|
||||
<Tag color="orange" className="text-xs">
|
||||
{config.topicPolicyConfig.topicsConfig?.length || 0} topic policy(s)
|
||||
</Tag>
|
||||
)}
|
||||
{config.contentPolicyConfig && (
|
||||
<Tag color="red" className="text-xs">
|
||||
{config.contentPolicyConfig.filtersConfig?.length || 0} content filter(s)
|
||||
</Tag>
|
||||
)}
|
||||
{config.wordPolicyConfig && (
|
||||
<Tag color="purple" className="text-xs">
|
||||
word policy
|
||||
</Tag>
|
||||
)}
|
||||
{config.sensitiveInformationPolicyConfig && (
|
||||
<Tag color="blue" className="text-xs">
|
||||
PII detection
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
const CredentialOption: React.FC<{
|
||||
credential: any;
|
||||
provider?: string;
|
||||
showProviderLogo?: boolean;
|
||||
}> = ({ credential, provider, showProviderLogo }) => (
|
||||
<div className="flex items-center gap-2">
|
||||
{showProviderLogo && provider && <ProviderLogo provider={provider} />}
|
||||
<span>{credential.credential_name}</span>
|
||||
{!showProviderLogo && credential.credential_info?.custom_llm_provider && (
|
||||
<Tag className="text-xs">{credential.credential_info.custom_llm_provider}</Tag>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
const PartnerGuardrailCard: React.FC<{
|
||||
pg: PartnerGuardrailConfig;
|
||||
isEnabled: boolean;
|
||||
onToggle: (checked: boolean) => void;
|
||||
selectedCredential?: string;
|
||||
onCredentialChange: (value: string) => void;
|
||||
selectedRegion?: string;
|
||||
onRegionChange: (value: string) => void;
|
||||
providerCredentials: any[];
|
||||
allCredentials: any[];
|
||||
credentialsLoading: boolean;
|
||||
}> = ({
|
||||
pg,
|
||||
isEnabled,
|
||||
onToggle,
|
||||
selectedCredential,
|
||||
onCredentialChange,
|
||||
selectedRegion,
|
||||
onRegionChange,
|
||||
providerCredentials,
|
||||
allCredentials,
|
||||
credentialsLoading,
|
||||
}) => {
|
||||
const credentialOptions = (providerCredentials.length > 0 ? providerCredentials : allCredentials).map(
|
||||
(c: any) => ({
|
||||
value: c.credential_name,
|
||||
label: (
|
||||
<CredentialOption
|
||||
credential={c}
|
||||
provider={pg.provider}
|
||||
showProviderLogo={providerCredentials.length > 0}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`border rounded-lg p-4 transition-colors ${
|
||||
isEnabled ? "bg-orange-50 border-orange-200" : "bg-gray-50 border-gray-200"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="flex-shrink-0 pt-0.5">
|
||||
<Switch size="small" checked={isEnabled} onChange={onToggle} />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<ProviderLogo provider={pg.provider} />
|
||||
<span className="text-sm font-medium text-gray-900">{pg.label}</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mb-3">{pg.description}</p>
|
||||
|
||||
{isEnabled && (
|
||||
<div className="space-y-3 pt-2 border-t border-gray-200">
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">
|
||||
Credential
|
||||
</label>
|
||||
<Select
|
||||
className="w-full"
|
||||
size="small"
|
||||
placeholder={credentialsLoading ? "Loading credentials..." : "Select a credential"}
|
||||
loading={credentialsLoading}
|
||||
value={selectedCredential}
|
||||
onChange={onCredentialChange}
|
||||
options={credentialOptions}
|
||||
notFoundContent={
|
||||
<div className="text-center py-2 text-gray-500 text-xs">
|
||||
No credentials found. Add one in Settings → Credentials.
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{pg.provider === "bedrock" && (
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">
|
||||
AWS Region
|
||||
</label>
|
||||
<Select
|
||||
className="w-full"
|
||||
size="small"
|
||||
placeholder="Select region (default: us-east-1)"
|
||||
value={selectedRegion}
|
||||
onChange={onRegionChange}
|
||||
options={AWS_REGIONS.map((r) => ({ value: r, label: r }))}
|
||||
allowClear
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ProvisionConfigTags config={pg.provision_config} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
||||
visible,
|
||||
template,
|
||||
|
|
@ -228,23 +39,21 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
new Set()
|
||||
);
|
||||
|
||||
// Partner guardrail state
|
||||
const [partnerEnabled, setPartnerEnabled] = useState<Record<string, boolean>>(
|
||||
{}
|
||||
);
|
||||
const [partnerEnabled, setPartnerEnabled] = useState<
|
||||
Record<string, boolean>
|
||||
>({});
|
||||
const [partnerCredentials, setPartnerCredentials] = useState<
|
||||
Record<string, string>
|
||||
>({});
|
||||
const [partnerRegions, setPartnerRegions] = useState<Record<string, string>>(
|
||||
{}
|
||||
);
|
||||
const [partnerRegions, setPartnerRegions] = useState<
|
||||
Record<string, string>
|
||||
>({});
|
||||
const [credentials, setCredentials] = useState<any[]>([]);
|
||||
const [credentialsLoading, setCredentialsLoading] = useState(false);
|
||||
|
||||
const partnerGuardrails: PartnerGuardrailConfig[] =
|
||||
const partnerGuardrailConfigs: PartnerGuardrailConfig[] =
|
||||
template?.partnerGuardrails || [];
|
||||
|
||||
// Prepare guardrail info with existence status
|
||||
const guardrailsInfo: GuardrailInfo[] = (
|
||||
template?.guardrailDefinitions || []
|
||||
).map((def: any) => ({
|
||||
|
|
@ -254,22 +63,18 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
definition: def,
|
||||
}));
|
||||
|
||||
// Initialize selection: select only new guardrails by default
|
||||
useEffect(() => {
|
||||
if (visible && template) {
|
||||
const newGuardrails = guardrailsInfo
|
||||
.filter((g) => !g.alreadyExists)
|
||||
.map((g) => g.guardrail_name);
|
||||
setSelectedGuardrails(new Set(newGuardrails));
|
||||
|
||||
// Reset partner state
|
||||
setPartnerEnabled({});
|
||||
setPartnerCredentials({});
|
||||
setPartnerRegions({});
|
||||
}
|
||||
}, [visible, template]);
|
||||
|
||||
// Fetch credentials when a partner guardrail is enabled
|
||||
useEffect(() => {
|
||||
const anyEnabled = Object.values(partnerEnabled).some(Boolean);
|
||||
if (anyEnabled && accessToken && credentials.length === 0) {
|
||||
|
|
@ -315,9 +120,8 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
.filter((g) => selectedGuardrails.has(g.guardrail_name))
|
||||
.map((g) => g.definition);
|
||||
|
||||
// Build partner guardrail selections
|
||||
const partnerSelections: PartnerGuardrailSelection[] = [];
|
||||
for (const pg of partnerGuardrails) {
|
||||
for (const pg of partnerGuardrailConfigs) {
|
||||
if (partnerEnabled[pg.provider] && partnerCredentials[pg.provider]) {
|
||||
partnerSelections.push({
|
||||
provider: pg.provider,
|
||||
|
|
@ -334,7 +138,6 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
);
|
||||
};
|
||||
|
||||
// Filter credentials by provider type
|
||||
const getCredentialsForProvider = (credentialProvider: string) => {
|
||||
return credentials.filter((c: any) => {
|
||||
const provider =
|
||||
|
|
@ -438,7 +241,9 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
<CheckCircleOutlined className="text-green-600 text-lg" />
|
||||
) : (
|
||||
<Checkbox
|
||||
checked={selectedGuardrails.has(guardrail.guardrail_name)}
|
||||
checked={selectedGuardrails.has(
|
||||
guardrail.guardrail_name
|
||||
)}
|
||||
onChange={() => handleToggle(guardrail.guardrail_name)}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -457,23 +262,28 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
<p className="text-sm text-gray-600">
|
||||
{guardrail.description}
|
||||
</p>
|
||||
|
||||
{/* Show guardrail type and mode */}
|
||||
<div className="flex gap-2 mt-2">
|
||||
<Tag className="text-xs">
|
||||
{guardrail.definition?.litellm_params?.guardrail || "unknown"}
|
||||
{guardrail.definition?.litellm_params?.guardrail ||
|
||||
"unknown"}
|
||||
</Tag>
|
||||
<Tag className="text-xs" color="blue">
|
||||
{guardrail.definition?.litellm_params?.mode || "unknown"}
|
||||
</Tag>
|
||||
{guardrail.definition?.litellm_params?.patterns && (
|
||||
<Tag className="text-xs" color="purple">
|
||||
{guardrail.definition.litellm_params.patterns.length} pattern(s)
|
||||
{
|
||||
guardrail.definition.litellm_params.patterns.length
|
||||
}{" "}
|
||||
pattern(s)
|
||||
</Tag>
|
||||
)}
|
||||
{guardrail.definition?.litellm_params?.categories && (
|
||||
<Tag className="text-xs" color="orange">
|
||||
{guardrail.definition.litellm_params.categories.length} category/categories
|
||||
{
|
||||
guardrail.definition.litellm_params.categories.length
|
||||
}{" "}
|
||||
category/categories
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -500,7 +310,8 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-lg">✨</span>
|
||||
<span className="font-medium text-purple-900 text-sm">
|
||||
AI-Discovered Competitors ({template.discoveredCompetitors.length})
|
||||
AI-Discovered Competitors (
|
||||
{template.discoveredCompetitors.length})
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
|
|
@ -511,14 +322,15 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
))}
|
||||
</div>
|
||||
<p className="text-xs text-purple-600 mt-2">
|
||||
These competitor names will be automatically blocked by the competitor-name-blocker guardrail.
|
||||
These competitor names will be automatically blocked by the
|
||||
competitor-name-blocker guardrail.
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Partner Guardrails Section */}
|
||||
{partnerGuardrails.length > 0 && (
|
||||
{partnerGuardrailConfigs.length > 0 && (
|
||||
<>
|
||||
<Divider />
|
||||
<div className="space-y-3">
|
||||
|
|
@ -534,23 +346,36 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
</Tag>
|
||||
</div>
|
||||
|
||||
{partnerGuardrails.map((pg) => (
|
||||
{partnerGuardrailConfigs.map((pg) => (
|
||||
<PartnerGuardrailCard
|
||||
key={pg.provider}
|
||||
pg={pg}
|
||||
isEnabled={partnerEnabled[pg.provider] || false}
|
||||
onToggle={(checked) =>
|
||||
setPartnerEnabled((prev) => ({ ...prev, [pg.provider]: checked }))
|
||||
setPartnerEnabled((prev) => ({
|
||||
...prev,
|
||||
[pg.provider]: checked,
|
||||
}))
|
||||
}
|
||||
selectedCredential={
|
||||
partnerCredentials[pg.provider] || undefined
|
||||
}
|
||||
selectedCredential={partnerCredentials[pg.provider] || undefined}
|
||||
onCredentialChange={(value) =>
|
||||
setPartnerCredentials((prev) => ({ ...prev, [pg.provider]: value }))
|
||||
setPartnerCredentials((prev) => ({
|
||||
...prev,
|
||||
[pg.provider]: value,
|
||||
}))
|
||||
}
|
||||
selectedRegion={partnerRegions[pg.provider] || undefined}
|
||||
onRegionChange={(value) =>
|
||||
setPartnerRegions((prev) => ({ ...prev, [pg.provider]: value }))
|
||||
setPartnerRegions((prev) => ({
|
||||
...prev,
|
||||
[pg.provider]: value,
|
||||
}))
|
||||
}
|
||||
providerCredentials={getCredentialsForProvider(pg.credential_provider)}
|
||||
providerCredentials={getCredentialsForProvider(
|
||||
pg.credential_provider
|
||||
)}
|
||||
allCredentials={credentials}
|
||||
credentialsLoading={credentialsLoading}
|
||||
/>
|
||||
|
|
@ -565,7 +390,9 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
<div className="text-sm text-gray-600">
|
||||
{selectedCount > 0 ? (
|
||||
<p>
|
||||
<span className="font-medium text-gray-900">{selectedCount}</span>{" "}
|
||||
<span className="font-medium text-gray-900">
|
||||
{selectedCount}
|
||||
</span>{" "}
|
||||
guardrail{selectedCount > 1 ? "s" : ""} will be created
|
||||
{Object.values(partnerEnabled).some(Boolean) && (
|
||||
<span className="text-orange-600">
|
||||
|
|
@ -576,11 +403,13 @@ const GuardrailSelectionModal: React.FC<GuardrailSelectionModalProps> = ({
|
|||
</p>
|
||||
) : existingCount > 0 ? (
|
||||
<p className="text-green-600">
|
||||
All guardrails already exist. You can proceed to use this template.
|
||||
All guardrails already exist. You can proceed to use this
|
||||
template.
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-orange-600">
|
||||
Select at least one guardrail to create, or click "Use Template" to proceed without creating new guardrails.
|
||||
Select at least one guardrail to create, or click "Use
|
||||
Template" to proceed without creating new guardrails.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
import React from "react";
|
||||
import { Tag, Select, Switch } from "antd";
|
||||
import {
|
||||
AWS_REGIONS,
|
||||
PartnerGuardrailConfig,
|
||||
partnerProviderLogoMap,
|
||||
} from "./types";
|
||||
|
||||
export const ProviderLogo: React.FC<{ provider: string }> = ({ provider }) => {
|
||||
const logoSrc = partnerProviderLogoMap[provider];
|
||||
if (logoSrc) {
|
||||
return (
|
||||
<img
|
||||
src={logoSrc}
|
||||
alt={provider}
|
||||
style={{ height: "20px", width: "20px", objectFit: "contain" }}
|
||||
onError={(e) => {
|
||||
e.currentTarget.style.display = "none";
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="w-5 h-5 rounded bg-gray-200 flex items-center justify-center text-xs font-bold text-gray-500">
|
||||
?
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ProvisionConfigTags: React.FC<{ config: Record<string, any> }> = ({
|
||||
config,
|
||||
}) => (
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{config.topicPolicyConfig && (
|
||||
<Tag color="orange" className="text-xs">
|
||||
{config.topicPolicyConfig.topicsConfig?.length || 0} topic policy(s)
|
||||
</Tag>
|
||||
)}
|
||||
{config.contentPolicyConfig && (
|
||||
<Tag color="red" className="text-xs">
|
||||
{config.contentPolicyConfig.filtersConfig?.length || 0} content
|
||||
filter(s)
|
||||
</Tag>
|
||||
)}
|
||||
{config.wordPolicyConfig && (
|
||||
<Tag color="purple" className="text-xs">
|
||||
word policy
|
||||
</Tag>
|
||||
)}
|
||||
{config.sensitiveInformationPolicyConfig && (
|
||||
<Tag color="blue" className="text-xs">
|
||||
PII detection
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
const CredentialOption: React.FC<{
|
||||
credential: any;
|
||||
provider?: string;
|
||||
showProviderLogo?: boolean;
|
||||
}> = ({ credential, provider, showProviderLogo }) => (
|
||||
<div className="flex items-center gap-2">
|
||||
{showProviderLogo && provider && <ProviderLogo provider={provider} />}
|
||||
<span>{credential.credential_name}</span>
|
||||
{!showProviderLogo && credential.credential_info?.custom_llm_provider && (
|
||||
<Tag className="text-xs">
|
||||
{credential.credential_info.custom_llm_provider}
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
export interface PartnerGuardrailCardProps {
|
||||
pg: PartnerGuardrailConfig;
|
||||
isEnabled: boolean;
|
||||
onToggle: (checked: boolean) => void;
|
||||
selectedCredential?: string;
|
||||
onCredentialChange: (value: string) => void;
|
||||
selectedRegion?: string;
|
||||
onRegionChange: (value: string) => void;
|
||||
providerCredentials: any[];
|
||||
allCredentials: any[];
|
||||
credentialsLoading: boolean;
|
||||
}
|
||||
|
||||
const PartnerGuardrailCard: React.FC<PartnerGuardrailCardProps> = ({
|
||||
pg,
|
||||
isEnabled,
|
||||
onToggle,
|
||||
selectedCredential,
|
||||
onCredentialChange,
|
||||
selectedRegion,
|
||||
onRegionChange,
|
||||
providerCredentials,
|
||||
allCredentials,
|
||||
credentialsLoading,
|
||||
}) => {
|
||||
const credentialOptions = (
|
||||
providerCredentials.length > 0 ? providerCredentials : allCredentials
|
||||
).map((c: any) => ({
|
||||
value: c.credential_name,
|
||||
label: (
|
||||
<CredentialOption
|
||||
credential={c}
|
||||
provider={pg.provider}
|
||||
showProviderLogo={providerCredentials.length > 0}
|
||||
/>
|
||||
),
|
||||
}));
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`border rounded-lg p-4 transition-colors ${
|
||||
isEnabled
|
||||
? "bg-orange-50 border-orange-200"
|
||||
: "bg-gray-50 border-gray-200"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="flex-shrink-0 pt-0.5">
|
||||
<Switch size="small" checked={isEnabled} onChange={onToggle} />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<ProviderLogo provider={pg.provider} />
|
||||
<span className="text-sm font-medium text-gray-900">
|
||||
{pg.label}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 mb-3">{pg.description}</p>
|
||||
|
||||
{isEnabled && (
|
||||
<div className="space-y-3 pt-2 border-t border-gray-200">
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">
|
||||
Credential
|
||||
</label>
|
||||
<Select
|
||||
className="w-full"
|
||||
size="small"
|
||||
placeholder={
|
||||
credentialsLoading
|
||||
? "Loading credentials..."
|
||||
: "Select a credential"
|
||||
}
|
||||
loading={credentialsLoading}
|
||||
value={selectedCredential}
|
||||
onChange={onCredentialChange}
|
||||
options={credentialOptions}
|
||||
notFoundContent={
|
||||
<div className="text-center py-2 text-gray-500 text-xs">
|
||||
No credentials found. Add one in Settings →
|
||||
Credentials.
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{pg.provider === "bedrock" && (
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">
|
||||
AWS Region
|
||||
</label>
|
||||
<Select
|
||||
className="w-full"
|
||||
size="small"
|
||||
placeholder="Select region (default: us-east-1)"
|
||||
value={selectedRegion}
|
||||
onChange={onRegionChange}
|
||||
options={AWS_REGIONS.map((r) => ({ value: r, label: r }))}
|
||||
allowClear
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ProvisionConfigTags config={pg.provision_config} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PartnerGuardrailCard;
|
||||
|
|
@ -8,6 +8,7 @@ import {
|
|||
CheckCircleIcon,
|
||||
} from "@heroicons/react/outline";
|
||||
import { getPolicyTemplates } from "../networking";
|
||||
import { partnerProviderLogoMap } from "./types";
|
||||
|
||||
interface PartnerGuardrailInfo {
|
||||
provider: string;
|
||||
|
|
@ -28,10 +29,6 @@ interface PolicyTemplateCardProps {
|
|||
onUseTemplate: () => void;
|
||||
}
|
||||
|
||||
const partnerProviderLogoMap: Record<string, string> = {
|
||||
bedrock: "../ui/assets/logos/bedrock.svg",
|
||||
};
|
||||
|
||||
const PolicyTemplateCard: React.FC<PolicyTemplateCardProps> = ({
|
||||
title,
|
||||
description,
|
||||
|
|
|
|||
|
|
@ -99,3 +99,45 @@ export interface PipelineTestResult {
|
|||
error_message: string | null;
|
||||
modify_response_message: string | null;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Guardrail selection modal types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export interface GuardrailInfo {
|
||||
guardrail_name: string;
|
||||
description: string;
|
||||
alreadyExists: boolean;
|
||||
definition: any;
|
||||
}
|
||||
|
||||
export interface PartnerGuardrailConfig {
|
||||
provider: string;
|
||||
label: string;
|
||||
description: string;
|
||||
credential_provider: string;
|
||||
provision_config: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface PartnerGuardrailSelection {
|
||||
provider: string;
|
||||
credential_name: string;
|
||||
provision_config: Record<string, any>;
|
||||
aws_region_name?: string;
|
||||
}
|
||||
|
||||
export const AWS_REGIONS = [
|
||||
"us-east-1",
|
||||
"us-east-2",
|
||||
"us-west-2",
|
||||
"eu-west-1",
|
||||
"eu-west-2",
|
||||
"eu-central-1",
|
||||
"ap-southeast-1",
|
||||
"ap-southeast-2",
|
||||
"ap-northeast-1",
|
||||
];
|
||||
|
||||
export const partnerProviderLogoMap: Record<string, string> = {
|
||||
bedrock: "../ui/assets/logos/bedrock.svg",
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue