mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
feat(ui): i18n for model info view
This commit is contained in:
parent
4018f9a836
commit
7c0faa8bc6
3 changed files with 342 additions and 132 deletions
|
|
@ -2,6 +2,7 @@ import { useModelCostMap } from "@/app/(dashboard)/hooks/models/useModelCostMap"
|
|||
import { useModelHub, useModelsInfo } from "@/app/(dashboard)/hooks/models/useModels";
|
||||
import { transformModelData } from "@/app/(dashboard)/models-and-endpoints/utils/modelDataTransformer";
|
||||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ArrowLeftIcon, KeyIcon, RefreshIcon, TrashIcon } from "@heroicons/react/outline";
|
||||
import {
|
||||
Card,
|
||||
|
|
@ -63,6 +64,7 @@ export default function ModelInfoView({
|
|||
onModelUpdate,
|
||||
modelAccessGroups,
|
||||
}: ModelInfoViewProps) {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const [localModelData, setLocalModelData] = useState<any>(null);
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
|
|
@ -220,9 +222,9 @@ export default function ModelInfoView({
|
|||
custom_llm_provider: localModelData.litellm_params?.custom_llm_provider,
|
||||
},
|
||||
};
|
||||
NotificationsManager.info("Storing credential..");
|
||||
NotificationsManager.info(t("modelInfoView.storingCredential"));
|
||||
let credentialResponse = await credentialCreateCall(accessToken, credentialItem);
|
||||
NotificationsManager.success("Credential stored successfully");
|
||||
NotificationsManager.success(t("modelInfoView.credentialStoredSuccess"));
|
||||
};
|
||||
|
||||
const handleModelUpdate = async (values: any) => {
|
||||
|
|
@ -236,7 +238,7 @@ export default function ModelInfoView({
|
|||
parsedExtraParams = values.litellm_extra_params ? JSON.parse(values.litellm_extra_params) : {};
|
||||
delete parsedExtraParams.litellm_credential_name;
|
||||
} catch (e) {
|
||||
NotificationsManager.fromBackend("Invalid JSON in LiteLLM Params");
|
||||
NotificationsManager.fromBackend(t("modelInfoView.invalidJsonLitellmParams"));
|
||||
setIsSaving(false);
|
||||
return;
|
||||
}
|
||||
|
|
@ -347,7 +349,7 @@ export default function ModelInfoView({
|
|||
};
|
||||
}
|
||||
} catch (e) {
|
||||
NotificationsManager.fromBackend("Invalid JSON in Model Info");
|
||||
NotificationsManager.fromBackend(t("modelInfoView.invalidJsonModelInfo"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -373,12 +375,12 @@ export default function ModelInfoView({
|
|||
onModelUpdate(updatedModelData);
|
||||
}
|
||||
|
||||
NotificationsManager.success("Model settings updated successfully");
|
||||
NotificationsManager.success(t("modelInfoView.modelSettingsUpdateSuccess"));
|
||||
setIsDirty(false);
|
||||
setIsEditing(false);
|
||||
} catch (error) {
|
||||
console.error("Error updating model:", error);
|
||||
NotificationsManager.fromBackend("Failed to update model settings");
|
||||
NotificationsManager.fromBackend(t("modelInfoView.modelSettingsUpdateFailed"));
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
|
@ -389,9 +391,9 @@ export default function ModelInfoView({
|
|||
return (
|
||||
<div className="p-4">
|
||||
<TremorButton icon={ArrowLeftIcon} variant="light" onClick={onClose} className="mb-4">
|
||||
Back to Models
|
||||
{t("modelInfoView.backToModels")}
|
||||
</TremorButton>
|
||||
<Text>Loading...</Text>
|
||||
<Text>{t("common.loading")}</Text>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -401,9 +403,9 @@ export default function ModelInfoView({
|
|||
return (
|
||||
<div className="p-4">
|
||||
<TremorButton icon={ArrowLeftIcon} variant="light" onClick={onClose} className="mb-4">
|
||||
Back to Models
|
||||
{t("modelInfoView.backToModels")}
|
||||
</TremorButton>
|
||||
<Text>Model not found</Text>
|
||||
<Text>{t("modelInfoView.modelNotFound")}</Text>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -411,7 +413,7 @@ export default function ModelInfoView({
|
|||
const handleTestConnection = async () => {
|
||||
if (!accessToken) return;
|
||||
try {
|
||||
NotificationsManager.info("Testing connection...");
|
||||
NotificationsManager.info(t("modelInfoView.testingConnection"));
|
||||
const response = await testConnectionRequest(
|
||||
accessToken,
|
||||
{
|
||||
|
|
@ -432,15 +434,17 @@ export default function ModelInfoView({
|
|||
);
|
||||
|
||||
if (response.status === "success") {
|
||||
NotificationsManager.success("Connection test successful!");
|
||||
NotificationsManager.success(t("modelInfoView.connectionTestSuccess"));
|
||||
} else {
|
||||
throw new Error(response?.result?.error || response?.message || "Unknown error");
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
NotificationsManager.error("Error testing connection: " + truncateString(error.message, 100));
|
||||
NotificationsManager.error(
|
||||
t("modelInfoView.connectionTestError", { error: truncateString(error.message, 100) }),
|
||||
);
|
||||
} else {
|
||||
NotificationsManager.error("Error testing connection: " + String(error));
|
||||
NotificationsManager.error(t("modelInfoView.connectionTestError", { error: String(error) }));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -450,7 +454,7 @@ export default function ModelInfoView({
|
|||
setDeleteLoading(true);
|
||||
if (!accessToken) return;
|
||||
await modelDeleteCall(accessToken, modelId);
|
||||
NotificationsManager.success("Model deleted successfully");
|
||||
NotificationsManager.success(t("modelInfoView.modelDeleteSuccess"));
|
||||
|
||||
if (onModelUpdate) {
|
||||
onModelUpdate({
|
||||
|
|
@ -462,7 +466,7 @@ export default function ModelInfoView({
|
|||
onClose();
|
||||
} catch (error) {
|
||||
console.error("Error deleting the model:", error);
|
||||
NotificationsManager.fromBackend("Failed to delete model");
|
||||
NotificationsManager.fromBackend(t("modelInfoView.modelDeleteFailed"));
|
||||
} finally {
|
||||
setDeleteLoading(false);
|
||||
setIsDeleteModalOpen(false);
|
||||
|
|
@ -492,9 +496,9 @@ export default function ModelInfoView({
|
|||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<TremorButton icon={ArrowLeftIcon} variant="light" onClick={onClose} className="mb-4">
|
||||
Back to Models
|
||||
{t("modelInfoView.backToModels")}
|
||||
</TremorButton>
|
||||
<Title>Public Model Name: {getDisplayModelName(modelData)}</Title>
|
||||
<Title>{t("modelInfoView.publicModelName", { name: getDisplayModelName(modelData) })}</Title>
|
||||
<div className="flex items-center cursor-pointer">
|
||||
<Text className="text-gray-500 font-mono">{modelData.model_info.id}</Text>
|
||||
<Button
|
||||
|
|
@ -518,7 +522,7 @@ export default function ModelInfoView({
|
|||
className="flex items-center gap-2"
|
||||
data-testid="test-connection-button"
|
||||
>
|
||||
Test Connection
|
||||
{t("modelInfoView.testConnection")}
|
||||
</TremorButton>
|
||||
|
||||
<TremorButton
|
||||
|
|
@ -529,7 +533,7 @@ export default function ModelInfoView({
|
|||
disabled={!isAdmin}
|
||||
data-testid="reuse-credentials-button"
|
||||
>
|
||||
Re-use Credentials
|
||||
{t("modelInfoView.reuseCredentials")}
|
||||
</TremorButton>
|
||||
<TremorButton
|
||||
icon={TrashIcon}
|
||||
|
|
@ -539,15 +543,15 @@ export default function ModelInfoView({
|
|||
disabled={!canEditModel}
|
||||
data-testid="delete-model-button"
|
||||
>
|
||||
Delete Model
|
||||
{t("modelInfoView.deleteModel")}
|
||||
</TremorButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TabGroup>
|
||||
<TabList className="mb-6">
|
||||
<Tab>Overview</Tab>
|
||||
<Tab>Raw JSON</Tab>
|
||||
<Tab>{t("modelInfoView.tabOverview")}</Tab>
|
||||
<Tab>{t("modelInfoView.tabRawJson")}</Tab>
|
||||
</TabList>
|
||||
|
||||
<TabPanels>
|
||||
|
|
@ -555,12 +559,12 @@ export default function ModelInfoView({
|
|||
{/* Overview Grid */}
|
||||
<Grid numItems={1} numItemsSm={2} numItemsLg={3} className="gap-6 mb-6">
|
||||
<Card>
|
||||
<Text>Provider</Text>
|
||||
<Text>{t("modelInfoView.provider")}</Text>
|
||||
<div className="mt-2 flex items-center space-x-2">
|
||||
{modelData.provider && (
|
||||
<img
|
||||
src={getProviderLogoAndName(modelData.provider).logo}
|
||||
alt={`${modelData.provider} logo`}
|
||||
alt={t("modelInfoView.providerLogoAlt", { provider: modelData.provider })}
|
||||
className="w-4 h-4"
|
||||
onError={(e) => {
|
||||
const target = e.currentTarget as HTMLImageElement;
|
||||
|
|
@ -581,24 +585,24 @@ export default function ModelInfoView({
|
|||
}}
|
||||
/>
|
||||
)}
|
||||
<Title>{modelData.provider || "Not Set"}</Title>
|
||||
<Title>{modelData.provider || t("modelInfoView.notSet")}</Title>
|
||||
</div>
|
||||
</Card>
|
||||
<Card>
|
||||
<Text>LiteLLM Model</Text>
|
||||
<Text>{t("modelInfoView.litellmModel")}</Text>
|
||||
<div className="mt-2 overflow-hidden">
|
||||
<Tooltip title={modelData.litellm_model_name || "Not Set"}>
|
||||
<Tooltip title={modelData.litellm_model_name || t("modelInfoView.notSet")}>
|
||||
<div className="break-all text-sm font-medium leading-relaxed cursor-pointer">
|
||||
{modelData.litellm_model_name || "Not Set"}
|
||||
{modelData.litellm_model_name || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Card>
|
||||
<Card>
|
||||
<Text>Pricing</Text>
|
||||
<Text>{t("modelInfoView.pricing")}</Text>
|
||||
<div className="mt-2">
|
||||
<Text>Input: ${modelData.input_cost}/1M tokens</Text>
|
||||
<Text>Output: ${modelData.output_cost}/1M tokens</Text>
|
||||
<Text>{t("modelInfoView.pricingInput", { cost: modelData.input_cost })}</Text>
|
||||
<Text>{t("modelInfoView.pricingOutput", { cost: modelData.output_cost })}</Text>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
|
@ -614,14 +618,14 @@ export default function ModelInfoView({
|
|||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
Created At{" "}
|
||||
{t("modelInfoView.createdAt")}{" "}
|
||||
{modelData.model_info.created_at
|
||||
? new Date(modelData.model_info.created_at).toLocaleDateString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
})
|
||||
: "Not Set"}
|
||||
: t("modelInfoView.notSet")}
|
||||
</div>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -632,28 +636,30 @@ export default function ModelInfoView({
|
|||
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
||||
/>
|
||||
</svg>
|
||||
Created By {modelData.model_info.created_by || "Not Set"}
|
||||
{t("modelInfoView.createdBy", {
|
||||
creator: modelData.model_info.created_by || t("modelInfoView.notSet"),
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Settings Card */}
|
||||
<Card>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title>Model Settings</Title>
|
||||
<Title>{t("modelInfoView.modelSettings")}</Title>
|
||||
<div className="flex gap-2">
|
||||
{isAutoRouter && canEditModel && !isEditing && (
|
||||
<TremorButton onClick={() => setIsAutoRouterModalOpen(true)} className="flex items-center">
|
||||
Edit Auto Router
|
||||
{t("modelInfoView.editAutoRouter")}
|
||||
</TremorButton>
|
||||
)}
|
||||
{canEditModel ? (
|
||||
!isEditing && (
|
||||
<TremorButton onClick={() => setIsEditing(true)} className="flex items-center">
|
||||
Edit Settings
|
||||
{t("modelInfoView.editSettings")}
|
||||
</TremorButton>
|
||||
)
|
||||
) : (
|
||||
<Tooltip title="Only DB models can be edited. You must be an admin or the creator of the model to edit it.">
|
||||
<Tooltip title={t("modelInfoView.editTooltip")}>
|
||||
<InfoCircleOutlined />
|
||||
</Tooltip>
|
||||
)}
|
||||
|
|
@ -728,10 +734,10 @@ export default function ModelInfoView({
|
|||
<div className="space-y-4">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text className="font-medium">Model Name</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldModelName")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="model_name" className="mb-0">
|
||||
<TextInput placeholder="Enter model name" />
|
||||
<TextInput placeholder={t("modelInfoView.placeholderModelName")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">{localModelData.model_name}</div>
|
||||
|
|
@ -739,10 +745,10 @@ export default function ModelInfoView({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">LiteLLM Model Name</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldLitellmModelName")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="litellm_model_name" className="mb-0">
|
||||
<TextInput placeholder="Enter LiteLLM model name" />
|
||||
<TextInput placeholder={t("modelInfoView.placeholderLitellmModelName")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">{localModelData.litellm_model_name}</div>
|
||||
|
|
@ -750,10 +756,10 @@ export default function ModelInfoView({
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Input Cost (per 1M tokens)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldInputCost")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="input_cost" className="mb-0">
|
||||
<NumericalInput placeholder="Enter input cost" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderInputCost")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
|
|
@ -761,16 +767,16 @@ export default function ModelInfoView({
|
|||
? (localModelData.litellm_params?.input_cost_per_token * 1_000_000).toFixed(4)
|
||||
: localModelData?.model_info?.input_cost_per_token
|
||||
? (localModelData.model_info.input_cost_per_token * 1_000_000).toFixed(4)
|
||||
: "Not Set"}
|
||||
: t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Output Cost (per 1M tokens)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldOutputCost")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="output_cost" className="mb-0">
|
||||
<NumericalInput placeholder="Enter output cost" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderOutputCost")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
|
|
@ -778,20 +784,20 @@ export default function ModelInfoView({
|
|||
? (localModelData.litellm_params.output_cost_per_token * 1_000_000).toFixed(4)
|
||||
: localModelData?.model_info?.output_cost_per_token
|
||||
? (localModelData.model_info.output_cost_per_token * 1_000_000).toFixed(4)
|
||||
: "Not Set"}
|
||||
: t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Cache Read Cost (per 1M tokens)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldCacheReadCost")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item
|
||||
name="cache_read_cost"
|
||||
className="mb-0"
|
||||
tooltip="If left blank on save, defaults to Input Cost."
|
||||
tooltip={t("modelInfoView.tooltipCacheReadCost")}
|
||||
>
|
||||
<NumericalInput placeholder="Defaults to Input Cost if blank" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderCacheReadCost")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
|
|
@ -801,20 +807,20 @@ export default function ModelInfoView({
|
|||
: localModelData?.model_info?.cache_read_input_token_cost !== undefined &&
|
||||
localModelData?.model_info?.cache_read_input_token_cost !== null
|
||||
? (localModelData.model_info.cache_read_input_token_cost * 1_000_000).toFixed(4)
|
||||
: "Not Set"}
|
||||
: t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Cache Write Cost (per 1M tokens)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldCacheWriteCost")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item
|
||||
name="cache_write_cost"
|
||||
className="mb-0"
|
||||
tooltip="If left blank on save, defaults to Input Cost (backend falls back to input_cost_per_token)."
|
||||
tooltip={t("modelInfoView.tooltipCacheWriteCost")}
|
||||
>
|
||||
<NumericalInput placeholder="Defaults to Input Cost if blank" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderCacheWriteCost")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
|
|
@ -824,123 +830,123 @@ export default function ModelInfoView({
|
|||
: localModelData?.model_info?.cache_creation_input_token_cost !== undefined &&
|
||||
localModelData?.model_info?.cache_creation_input_token_cost !== null
|
||||
? (localModelData.model_info.cache_creation_input_token_cost * 1_000_000).toFixed(4)
|
||||
: "Not Set"}
|
||||
: t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">API Base</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldApiBase")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="api_base" className="mb-0">
|
||||
<TextInput placeholder="Enter API base" />
|
||||
<TextInput placeholder={t("modelInfoView.placeholderApiBase")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.api_base || "Not Set"}
|
||||
{localModelData.litellm_params?.api_base || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Custom LLM Provider</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldCustomLlmProvider")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="custom_llm_provider" className="mb-0">
|
||||
<TextInput placeholder="Enter custom LLM provider" />
|
||||
<TextInput placeholder={t("modelInfoView.placeholderCustomLlmProvider")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.custom_llm_provider || "Not Set"}
|
||||
{localModelData.litellm_params?.custom_llm_provider || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Organization</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldOrganization")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="organization" className="mb-0">
|
||||
<TextInput placeholder="Enter organization" />
|
||||
<TextInput placeholder={t("modelInfoView.placeholderOrganization")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.organization || "Not Set"}
|
||||
{localModelData.litellm_params?.organization || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">TPM (Tokens per Minute)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldTpm")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="tpm" className="mb-0">
|
||||
<NumericalInput placeholder="Enter TPM" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderTpm")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.tpm || "Not Set"}
|
||||
{localModelData.litellm_params?.tpm || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">RPM (Requests per Minute)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldRpm")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="rpm" className="mb-0">
|
||||
<NumericalInput placeholder="Enter RPM" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderRpm")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.rpm || "Not Set"}
|
||||
{localModelData.litellm_params?.rpm || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Max Retries</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldMaxRetries")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="max_retries" className="mb-0">
|
||||
<NumericalInput placeholder="Enter max retries" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderMaxRetries")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.max_retries || "Not Set"}
|
||||
{localModelData.litellm_params?.max_retries || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Timeout (seconds)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldTimeout")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="timeout" className="mb-0">
|
||||
<NumericalInput placeholder="Enter timeout" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderTimeout")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.timeout || "Not Set"}
|
||||
{localModelData.litellm_params?.timeout || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Stream Timeout (seconds)</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldStreamTimeout")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="stream_timeout" className="mb-0">
|
||||
<NumericalInput placeholder="Enter stream timeout" />
|
||||
<NumericalInput placeholder={t("modelInfoView.placeholderStreamTimeout")} />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.stream_timeout || "Not Set"}
|
||||
{localModelData.litellm_params?.stream_timeout || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Model Access Groups</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldModelAccessGroups")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="model_access_group" className="mb-0">
|
||||
<Select
|
||||
mode="tags"
|
||||
showSearch
|
||||
placeholder="Select existing groups or type to create new ones"
|
||||
placeholder={t("modelInfoView.placeholderModelAccessGroups")}
|
||||
optionFilterProp="children"
|
||||
tokenSeparators={[","]}
|
||||
maxTagCount="responsive"
|
||||
|
|
@ -968,13 +974,13 @@ export default function ModelInfoView({
|
|||
))}
|
||||
</div>
|
||||
) : (
|
||||
"No groups assigned"
|
||||
t("modelInfoView.noGroupsAssigned")
|
||||
)
|
||||
) : (
|
||||
localModelData.model_info.access_groups
|
||||
)
|
||||
) : (
|
||||
"Not Set"
|
||||
t("modelInfoView.notSet")
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -982,8 +988,8 @@ export default function ModelInfoView({
|
|||
|
||||
<div>
|
||||
<Text className="font-medium">
|
||||
Guardrails
|
||||
<Tooltip title="Apply safety guardrails to this model to filter content or enforce policies">
|
||||
{t("modelInfoView.fieldGuardrails")}
|
||||
<Tooltip title={t("modelInfoView.tooltipGuardrails")}>
|
||||
<a
|
||||
href="https://docs.litellm.ai/docs/proxy/guardrails/quick_start"
|
||||
target="_blank"
|
||||
|
|
@ -999,7 +1005,7 @@ export default function ModelInfoView({
|
|||
<Select
|
||||
mode="tags"
|
||||
showSearch
|
||||
placeholder="Select existing guardrails or type to create new ones"
|
||||
placeholder={t("modelInfoView.placeholderGuardrails")}
|
||||
optionFilterProp="children"
|
||||
tokenSeparators={[","]}
|
||||
maxTagCount="responsive"
|
||||
|
|
@ -1029,13 +1035,13 @@ export default function ModelInfoView({
|
|||
)}
|
||||
</div>
|
||||
) : (
|
||||
"No guardrails assigned"
|
||||
t("modelInfoView.noGuardrailsAssigned")
|
||||
)
|
||||
) : (
|
||||
localModelData.litellm_params.guardrails
|
||||
)
|
||||
) : (
|
||||
"Not Set"
|
||||
t("modelInfoView.notSet")
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -1043,8 +1049,8 @@ export default function ModelInfoView({
|
|||
|
||||
<div>
|
||||
<Text className="font-medium">
|
||||
Attached Knowledge Bases (RAG)
|
||||
<Tooltip title="Vector stores used for RAG. Every request to this model will automatically retrieve context from these knowledge bases.">
|
||||
{t("modelInfoView.fieldKnowledgeBases")}
|
||||
<Tooltip title={t("modelInfoView.tooltipKnowledgeBases")}>
|
||||
<a
|
||||
href="https://docs.litellm.ai/docs/completion/knowledgebase"
|
||||
target="_blank"
|
||||
|
|
@ -1060,7 +1066,7 @@ export default function ModelInfoView({
|
|||
<VectorStoreSelector
|
||||
onChange={() => {}}
|
||||
accessToken={accessToken || ""}
|
||||
placeholder="Select knowledge bases (optional)"
|
||||
placeholder={t("modelInfoView.placeholderKnowledgeBases")}
|
||||
/>
|
||||
</Form.Item>
|
||||
) : (
|
||||
|
|
@ -1081,26 +1087,26 @@ export default function ModelInfoView({
|
|||
)}
|
||||
</div>
|
||||
) : (
|
||||
"No knowledge bases attached"
|
||||
t("modelInfoView.noKnowledgeBasesAttached")
|
||||
)
|
||||
) : (
|
||||
String(localModelData.litellm_params.vector_store_ids)
|
||||
)
|
||||
) : (
|
||||
"Not Set"
|
||||
t("modelInfoView.notSet")
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Tags</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldTags")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="tags" className="mb-0">
|
||||
<Select
|
||||
mode="tags"
|
||||
showSearch
|
||||
placeholder="Select existing tags or type to create new ones"
|
||||
placeholder={t("modelInfoView.placeholderTags")}
|
||||
optionFilterProp="children"
|
||||
tokenSeparators={[","]}
|
||||
maxTagCount="responsive"
|
||||
|
|
@ -1129,30 +1135,30 @@ export default function ModelInfoView({
|
|||
))}
|
||||
</div>
|
||||
) : (
|
||||
"No tags assigned"
|
||||
t("modelInfoView.noTagsAssigned")
|
||||
)
|
||||
) : (
|
||||
localModelData.litellm_params.tags
|
||||
)
|
||||
) : (
|
||||
"Not Set"
|
||||
t("modelInfoView.notSet")
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Existing Credentials</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldExistingCredentials")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="litellm_credential_name" className="mb-0">
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="Select or search for existing credentials"
|
||||
placeholder={t("modelInfoView.placeholderCredentials")}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input, option) =>
|
||||
(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
|
||||
}
|
||||
options={[
|
||||
{ value: "", label: "None" },
|
||||
{ value: "", label: t("common.none") },
|
||||
...credentialsList.map((credential) => ({
|
||||
value: credential.credential_name,
|
||||
label: credential.credential_name,
|
||||
|
|
@ -1163,19 +1169,20 @@ export default function ModelInfoView({
|
|||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.litellm_credential_name || "Manual"}
|
||||
{localModelData.litellm_params?.litellm_credential_name ||
|
||||
t("modelInfoView.credentialManual")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isWildcardModel && (
|
||||
<div>
|
||||
<Text className="font-medium">Health Check Model</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldHealthCheckModel")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="health_check_model" className="mb-0">
|
||||
<Select
|
||||
showSearch
|
||||
placeholder="Select existing health check model"
|
||||
placeholder={t("modelInfoView.placeholderHealthCheckModel")}
|
||||
optionFilterProp="children"
|
||||
allowClear
|
||||
options={(() => {
|
||||
|
|
@ -1199,7 +1206,7 @@ export default function ModelInfoView({
|
|||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.model_info?.health_check_model || "Not Set"}
|
||||
{localModelData.model_info?.health_check_model || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -1214,31 +1221,36 @@ export default function ModelInfoView({
|
|||
/>
|
||||
) : (
|
||||
<div>
|
||||
<Text className="font-medium">Cache Control</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldCacheControl")}</Text>
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{localModelData.litellm_params?.cache_control_injection_points ? (
|
||||
<div>
|
||||
<p>Enabled</p>
|
||||
<p>{t("common.enabled")}</p>
|
||||
<div className="mt-2">
|
||||
{localModelData.litellm_params.cache_control_injection_points.map(
|
||||
(point: any, i: number) => (
|
||||
<div key={i} className="text-sm text-gray-600 mb-1">
|
||||
Location: {point.location},{point.role && <span> Role: {point.role}</span>}
|
||||
{point.index !== undefined && <span> Index: {point.index}</span>}
|
||||
{t("modelInfoView.cacheControlLocation", { location: point.location })}
|
||||
{point.role && (
|
||||
<span> {t("modelInfoView.cacheControlRole", { role: point.role })}</span>
|
||||
)}
|
||||
{point.index !== undefined && (
|
||||
<span> {t("modelInfoView.cacheControlIndex", { index: point.index })}</span>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
"Disabled"
|
||||
t("common.disabled")
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Text className="font-medium">Model Info</Text>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldModelInfo")}</Text>
|
||||
{isEditing ? (
|
||||
<Form.Item name="model_info" className="mb-0">
|
||||
<Input.TextArea
|
||||
|
|
@ -1257,8 +1269,8 @@ export default function ModelInfoView({
|
|||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">
|
||||
LiteLLM Params
|
||||
<Tooltip title="Optional litellm params used for making a litellm.completion() call. Some params are automatically added by LiteLLM.">
|
||||
{t("modelInfoView.fieldLitellmParams")}
|
||||
<Tooltip title={t("modelInfoView.tooltipLitellmParams")}>
|
||||
<a
|
||||
href="https://docs.litellm.ai/docs/completion/input"
|
||||
target="_blank"
|
||||
|
|
@ -1289,8 +1301,10 @@ export default function ModelInfoView({
|
|||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium">Team ID</Text>
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">{modelData.model_info.team_id || "Not Set"}</div>
|
||||
<Text className="font-medium">{t("modelInfoView.fieldTeamId")}</Text>
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded">
|
||||
{modelData.model_info.team_id || t("modelInfoView.notSet")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -1305,17 +1319,17 @@ export default function ModelInfoView({
|
|||
}}
|
||||
disabled={isSaving}
|
||||
>
|
||||
Cancel
|
||||
{t("common.cancel")}
|
||||
</TremorButton>
|
||||
<TremorButton variant="primary" onClick={() => form.submit()} loading={isSaving}>
|
||||
Save Changes
|
||||
{t("modelInfoView.saveChanges")}
|
||||
</TremorButton>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
) : (
|
||||
<Text>Loading...</Text>
|
||||
<Text>{t("common.loading")}</Text>
|
||||
)}
|
||||
</Card>
|
||||
</TabPanel>
|
||||
|
|
@ -1330,26 +1344,26 @@ export default function ModelInfoView({
|
|||
|
||||
<DeleteResourceModal
|
||||
isOpen={isDeleteModalOpen}
|
||||
title="Delete Model"
|
||||
alertMessage="This action cannot be undone."
|
||||
message="Are you sure you want to delete this model?"
|
||||
resourceInformationTitle="Model Information"
|
||||
title={t("modelInfoView.deleteModalTitle")}
|
||||
alertMessage={t("modelInfoView.deleteModalAlert")}
|
||||
message={t("modelInfoView.deleteModalMessage")}
|
||||
resourceInformationTitle={t("modelInfoView.deleteModalResourceTitle")}
|
||||
resourceInformation={[
|
||||
{
|
||||
label: "Model Name",
|
||||
value: modelData?.model_name || "Not Set",
|
||||
label: t("modelInfoView.fieldModelName"),
|
||||
value: modelData?.model_name || t("modelInfoView.notSet"),
|
||||
},
|
||||
{
|
||||
label: "LiteLLM Model Name",
|
||||
value: modelData?.litellm_model_name || "Not Set",
|
||||
label: t("modelInfoView.fieldLitellmModelName"),
|
||||
value: modelData?.litellm_model_name || t("modelInfoView.notSet"),
|
||||
},
|
||||
{
|
||||
label: "Provider",
|
||||
value: modelData?.provider || "Not Set",
|
||||
label: t("modelInfoView.provider"),
|
||||
value: modelData?.provider || t("modelInfoView.notSet"),
|
||||
},
|
||||
{
|
||||
label: "Created By",
|
||||
value: modelData?.model_info?.created_by || "Not Set",
|
||||
label: t("modelInfoView.createdByLabel"),
|
||||
value: modelData?.model_info?.created_by || t("modelInfoView.notSet"),
|
||||
},
|
||||
]}
|
||||
onCancel={() => setIsDeleteModalOpen(false)}
|
||||
|
|
@ -1369,7 +1383,7 @@ export default function ModelInfoView({
|
|||
<Modal
|
||||
open={isCredentialModalOpen}
|
||||
onCancel={() => setIsCredentialModalOpen(false)}
|
||||
title="Using Existing Credential"
|
||||
title={t("modelInfoView.usingExistingCredentialTitle")}
|
||||
>
|
||||
<Text>{modelData.litellm_params.litellm_credential_name}</Text>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -1299,6 +1299,104 @@
|
|||
"public": "Public",
|
||||
"infoShort": "Info"
|
||||
},
|
||||
"modelInfoView": {
|
||||
"backToModels": "Back to Models",
|
||||
"publicModelName": "Public Model Name: {{name}}",
|
||||
"modelNotFound": "Model not found",
|
||||
"testConnection": "Test Connection",
|
||||
"reuseCredentials": "Re-use Credentials",
|
||||
"deleteModel": "Delete Model",
|
||||
"tabOverview": "Overview",
|
||||
"tabRawJson": "Raw JSON",
|
||||
"provider": "Provider",
|
||||
"providerLogoAlt": "{{provider}} logo",
|
||||
"notSet": "Not Set",
|
||||
"litellmModel": "LiteLLM Model",
|
||||
"pricing": "Pricing",
|
||||
"pricingInput": "Input: ${{cost}}/1M tokens",
|
||||
"pricingOutput": "Output: ${{cost}}/1M tokens",
|
||||
"createdAt": "Created At",
|
||||
"createdBy": "Created By {{creator}}",
|
||||
"createdByLabel": "Created By",
|
||||
"modelSettings": "Model Settings",
|
||||
"editAutoRouter": "Edit Auto Router",
|
||||
"editSettings": "Edit Settings",
|
||||
"editTooltip": "Only DB models can be edited. You must be an admin or the creator of the model to edit it.",
|
||||
"fieldModelName": "Model Name",
|
||||
"placeholderModelName": "Enter model name",
|
||||
"fieldLitellmModelName": "LiteLLM Model Name",
|
||||
"placeholderLitellmModelName": "Enter LiteLLM model name",
|
||||
"fieldInputCost": "Input Cost (per 1M tokens)",
|
||||
"placeholderInputCost": "Enter input cost",
|
||||
"fieldOutputCost": "Output Cost (per 1M tokens)",
|
||||
"placeholderOutputCost": "Enter output cost",
|
||||
"fieldCacheReadCost": "Cache Read Cost (per 1M tokens)",
|
||||
"tooltipCacheReadCost": "If left blank on save, defaults to Input Cost.",
|
||||
"placeholderCacheReadCost": "Defaults to Input Cost if blank",
|
||||
"fieldCacheWriteCost": "Cache Write Cost (per 1M tokens)",
|
||||
"tooltipCacheWriteCost": "If left blank on save, defaults to Input Cost (backend falls back to input_cost_per_token).",
|
||||
"placeholderCacheWriteCost": "Defaults to Input Cost if blank",
|
||||
"fieldApiBase": "API Base",
|
||||
"placeholderApiBase": "Enter API base",
|
||||
"fieldCustomLlmProvider": "Custom LLM Provider",
|
||||
"placeholderCustomLlmProvider": "Enter custom LLM provider",
|
||||
"fieldOrganization": "Organization",
|
||||
"placeholderOrganization": "Enter organization",
|
||||
"fieldTpm": "TPM (Tokens per Minute)",
|
||||
"placeholderTpm": "Enter TPM",
|
||||
"fieldRpm": "RPM (Requests per Minute)",
|
||||
"placeholderRpm": "Enter RPM",
|
||||
"fieldMaxRetries": "Max Retries",
|
||||
"placeholderMaxRetries": "Enter max retries",
|
||||
"fieldTimeout": "Timeout (seconds)",
|
||||
"placeholderTimeout": "Enter timeout",
|
||||
"fieldStreamTimeout": "Stream Timeout (seconds)",
|
||||
"placeholderStreamTimeout": "Enter stream timeout",
|
||||
"fieldModelAccessGroups": "Model Access Groups",
|
||||
"placeholderModelAccessGroups": "Select existing groups or type to create new ones",
|
||||
"noGroupsAssigned": "No groups assigned",
|
||||
"fieldGuardrails": "Guardrails",
|
||||
"tooltipGuardrails": "Apply safety guardrails to this model to filter content or enforce policies",
|
||||
"placeholderGuardrails": "Select existing guardrails or type to create new ones",
|
||||
"noGuardrailsAssigned": "No guardrails assigned",
|
||||
"fieldKnowledgeBases": "Attached Knowledge Bases (RAG)",
|
||||
"tooltipKnowledgeBases": "Vector stores used for RAG. Every request to this model will automatically retrieve context from these knowledge bases.",
|
||||
"placeholderKnowledgeBases": "Select knowledge bases (optional)",
|
||||
"noKnowledgeBasesAttached": "No knowledge bases attached",
|
||||
"fieldTags": "Tags",
|
||||
"placeholderTags": "Select existing tags or type to create new ones",
|
||||
"noTagsAssigned": "No tags assigned",
|
||||
"fieldExistingCredentials": "Existing Credentials",
|
||||
"placeholderCredentials": "Select or search for existing credentials",
|
||||
"credentialManual": "Manual",
|
||||
"fieldHealthCheckModel": "Health Check Model",
|
||||
"placeholderHealthCheckModel": "Select existing health check model",
|
||||
"fieldCacheControl": "Cache Control",
|
||||
"cacheControlLocation": "Location: {{location}},",
|
||||
"cacheControlRole": "Role: {{role}}",
|
||||
"cacheControlIndex": "Index: {{index}}",
|
||||
"fieldModelInfo": "Model Info",
|
||||
"fieldLitellmParams": "LiteLLM Params",
|
||||
"tooltipLitellmParams": "Optional litellm params used for making a litellm.completion() call. Some params are automatically added by LiteLLM.",
|
||||
"fieldTeamId": "Team ID",
|
||||
"saveChanges": "Save Changes",
|
||||
"deleteModalTitle": "Delete Model",
|
||||
"deleteModalAlert": "This action cannot be undone.",
|
||||
"deleteModalMessage": "Are you sure you want to delete this model?",
|
||||
"deleteModalResourceTitle": "Model Information",
|
||||
"usingExistingCredentialTitle": "Using Existing Credential",
|
||||
"storingCredential": "Storing credential..",
|
||||
"credentialStoredSuccess": "Credential stored successfully",
|
||||
"invalidJsonLitellmParams": "Invalid JSON in LiteLLM Params",
|
||||
"invalidJsonModelInfo": "Invalid JSON in Model Info",
|
||||
"modelSettingsUpdateSuccess": "Model settings updated successfully",
|
||||
"modelSettingsUpdateFailed": "Failed to update model settings",
|
||||
"testingConnection": "Testing connection...",
|
||||
"connectionTestSuccess": "Connection test successful!",
|
||||
"connectionTestError": "Error testing connection: {{error}}",
|
||||
"modelDeleteSuccess": "Model deleted successfully",
|
||||
"modelDeleteFailed": "Failed to delete model"
|
||||
},
|
||||
"common": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
|
|
|
|||
|
|
@ -1299,6 +1299,104 @@
|
|||
"public": "公开",
|
||||
"infoShort": "详情"
|
||||
},
|
||||
"modelInfoView": {
|
||||
"backToModels": "返回模型列表",
|
||||
"publicModelName": "公开模型名称:{{name}}",
|
||||
"modelNotFound": "未找到模型",
|
||||
"testConnection": "测试连接",
|
||||
"reuseCredentials": "复用凭据",
|
||||
"deleteModel": "删除模型",
|
||||
"tabOverview": "概览",
|
||||
"tabRawJson": "原始 JSON",
|
||||
"provider": "提供商",
|
||||
"providerLogoAlt": "{{provider}} 标志",
|
||||
"notSet": "未设置",
|
||||
"litellmModel": "LiteLLM 模型",
|
||||
"pricing": "定价",
|
||||
"pricingInput": "输入:${{cost}}/百万 Token",
|
||||
"pricingOutput": "输出:${{cost}}/百万 Token",
|
||||
"createdAt": "创建时间",
|
||||
"createdBy": "创建者:{{creator}}",
|
||||
"createdByLabel": "创建者",
|
||||
"modelSettings": "模型设置",
|
||||
"editAutoRouter": "编辑自动路由器",
|
||||
"editSettings": "编辑设置",
|
||||
"editTooltip": "只有数据库模型可以编辑。您必须是管理员或该模型的创建者才能编辑。",
|
||||
"fieldModelName": "模型名称",
|
||||
"placeholderModelName": "输入模型名称",
|
||||
"fieldLitellmModelName": "LiteLLM 模型名称",
|
||||
"placeholderLitellmModelName": "输入 LiteLLM 模型名称",
|
||||
"fieldInputCost": "输入费用(每百万 Token)",
|
||||
"placeholderInputCost": "输入输入费用",
|
||||
"fieldOutputCost": "输出费用(每百万 Token)",
|
||||
"placeholderOutputCost": "输入输出费用",
|
||||
"fieldCacheReadCost": "缓存读取费用(每百万 Token)",
|
||||
"tooltipCacheReadCost": "保存时若留空,默认使用输入费用。",
|
||||
"placeholderCacheReadCost": "留空则默认使用输入费用",
|
||||
"fieldCacheWriteCost": "缓存写入费用(每百万 Token)",
|
||||
"tooltipCacheWriteCost": "保存时若留空,默认使用输入费用(后端回退到 input_cost_per_token)。",
|
||||
"placeholderCacheWriteCost": "留空则默认使用输入费用",
|
||||
"fieldApiBase": "API 基础地址",
|
||||
"placeholderApiBase": "输入 API 基础地址",
|
||||
"fieldCustomLlmProvider": "自定义 LLM 提供商",
|
||||
"placeholderCustomLlmProvider": "输入自定义 LLM 提供商",
|
||||
"fieldOrganization": "组织",
|
||||
"placeholderOrganization": "输入组织",
|
||||
"fieldTpm": "TPM(每分钟 Token 数)",
|
||||
"placeholderTpm": "输入 TPM",
|
||||
"fieldRpm": "RPM(每分钟请求数)",
|
||||
"placeholderRpm": "输入 RPM",
|
||||
"fieldMaxRetries": "最大重试次数",
|
||||
"placeholderMaxRetries": "输入最大重试次数",
|
||||
"fieldTimeout": "超时(秒)",
|
||||
"placeholderTimeout": "输入超时时间",
|
||||
"fieldStreamTimeout": "流式超时(秒)",
|
||||
"placeholderStreamTimeout": "输入流式超时时间",
|
||||
"fieldModelAccessGroups": "模型访问组",
|
||||
"placeholderModelAccessGroups": "选择现有访问组或输入新组名",
|
||||
"noGroupsAssigned": "未分配访问组",
|
||||
"fieldGuardrails": "护栏",
|
||||
"tooltipGuardrails": "为此模型应用安全护栏以过滤内容或执行策略",
|
||||
"placeholderGuardrails": "选择现有护栏或输入新的护栏",
|
||||
"noGuardrailsAssigned": "未分配护栏",
|
||||
"fieldKnowledgeBases": "关联知识库(RAG)",
|
||||
"tooltipKnowledgeBases": "用于 RAG 的向量存储。每次请求此模型时将自动从这些知识库中检索上下文。",
|
||||
"placeholderKnowledgeBases": "选择知识库(可选)",
|
||||
"noKnowledgeBasesAttached": "未关联知识库",
|
||||
"fieldTags": "标签",
|
||||
"placeholderTags": "选择现有标签或输入新标签",
|
||||
"noTagsAssigned": "未分配标签",
|
||||
"fieldExistingCredentials": "现有凭据",
|
||||
"placeholderCredentials": "选择或搜索现有凭据",
|
||||
"credentialManual": "手动",
|
||||
"fieldHealthCheckModel": "健康检查模型",
|
||||
"placeholderHealthCheckModel": "选择现有健康检查模型",
|
||||
"fieldCacheControl": "缓存控制",
|
||||
"cacheControlLocation": "位置:{{location}},",
|
||||
"cacheControlRole": "角色:{{role}}",
|
||||
"cacheControlIndex": "索引:{{index}}",
|
||||
"fieldModelInfo": "模型信息",
|
||||
"fieldLitellmParams": "LiteLLM 参数",
|
||||
"tooltipLitellmParams": "用于调用 litellm.completion() 的可选参数,部分参数由 LiteLLM 自动添加。",
|
||||
"fieldTeamId": "团队 ID",
|
||||
"saveChanges": "保存更改",
|
||||
"deleteModalTitle": "删除模型",
|
||||
"deleteModalAlert": "此操作无法撤销。",
|
||||
"deleteModalMessage": "确定要删除此模型吗?",
|
||||
"deleteModalResourceTitle": "模型信息",
|
||||
"usingExistingCredentialTitle": "使用现有凭据",
|
||||
"storingCredential": "正在存储凭据...",
|
||||
"credentialStoredSuccess": "凭据已成功存储",
|
||||
"invalidJsonLitellmParams": "LiteLLM 参数中存在无效的 JSON",
|
||||
"invalidJsonModelInfo": "模型信息中存在无效的 JSON",
|
||||
"modelSettingsUpdateSuccess": "模型设置已成功更新",
|
||||
"modelSettingsUpdateFailed": "更新模型设置失败",
|
||||
"testingConnection": "正在测试连接...",
|
||||
"connectionTestSuccess": "连接测试成功!",
|
||||
"connectionTestError": "测试连接时出错:{{error}}",
|
||||
"modelDeleteSuccess": "模型已成功删除",
|
||||
"modelDeleteFailed": "删除模型失败"
|
||||
},
|
||||
"common": {
|
||||
"save": "保存",
|
||||
"cancel": "取消",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue